题目链接:
P2842 纸币问题 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P2840 纸币问题 2 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P2834 纸币问题 3 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
纸币问题1
题目描述
某国有 n 种纸币,每种纸币面额为 ai 并且有无限张,现在要凑出 w 的金额,试问最少用多少张纸币可以凑出来?
输入格式
第一行两个整数 ,n,w,分别表示纸币的种数和要凑出的金额。
第二行一行 n 个以空格隔开的整数 a1,a2,a3,…an 依次表示这 n 种纸币的面额。输出格式
一行一个整数,表示最少使用的纸币张数。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
void solve() {
int dp[10001];
memset(dp,0,sizeof(dp));
//dp[amount]=min(dp[amount-amount[1-5])
int amount[1001];
int n,money;
cin>>n>>money;
for(int i=1;i<=n;i++)
{
cin>>amount[i];
dp[amount[i]]=1;
}
for(int i=1;i<=money;i++)
{
for(int j=1;j<=n;j++)
{
if(i>=amount[j])
{
if(dp[i]!=0&&dp[i-amount[j]]!=0)
{
dp[i]=min(dp[i],dp[i-amount[j]]+1);
}
else if(dp[i-amount[j]]!=0)
{
dp[i]=dp[i-amount[j]]+1;
}
}
}
}
cout<<dp[money];
}
signed main() {
ll t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
纸币问题2
题目描述
你有 n 种面额互不相同的纸币,第 i 种纸币的面额为 ai 并且有无限张,现在你需要支付 w 的金额,求问有多少种方式可以支付面额 w,答案对 10e9+7 取模。
注意在这里,同样的纸币组合如果支付顺序不同,会被视作不同的方式。例如支付 3 元,使用一张面值 1 的纸币和一张面值 2 的纸币会产生两种方式(1+2 和2+1)。输入格式
第一行两个正整数n,w,分别表示纸币的种数和要凑出的金额。
第二行一行 n 个以空格隔开的正整数 a1,a2,…an 依次表示这 n 种纸币的面额。输出格式
一行一个整数,表示支付方式的数量。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
void solve() {
ll sum=1e9+7;
ll dp[100001];
memset(dp,0,sizeof(dp));
//dp[amount]=min(dp[amount-amount[1-5])
ll amount[10001];
int n,money;
cin>>n>>money;
for(int i=1;i<=n;i++)
{
cin>>amount[i];
dp[amount[i]]=1;
}
for(int i=0;i<=money;i++)
{
for(int j=1;j<=n;j++)
{
dp[i+amount[j]]+=dp[i];
if(dp[i+amount[j]]>=sum)
{
dp[i+amount[j]]%=sum;
}
}
}
cout<<dp[money];
}
signed main() {
ll t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
纸币问题3
题目描述
你有 n 种面额互不相同的纸币,第 i 种纸币的面额为 ai 并且有无限张,现在你需要支付 w 的金额,请问有多少种纸币组合能恰好支付金额 w,答案对 10e9+7 取模。
输入格式
第一行两个正整数n,w,分别表示纸币的种数和要凑出的金额。
第二行一行 n 个以空格隔开的正整数 a1,a2,…an 依次表示这 n 种纸币的面额。输出格式
一行一个整数,表示能恰好凑齐面额 w 的纸币组合数量。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
int n,m;
void solve() {
cin>>n>>m;
int dp[n+1];// 剩余时间中的最大价值
fill(dp,dp+n+1,0);
int dp1[n+1];//或者有n时间下的最大价值
fill(dp1,dp1+n+1,0);
for(int i=1;i<=m;i++)
{
int o1,o2;
cin>>o1>>o2;
if(o1<=n)
{
for(int j=o1;j<=n;j++)
{
dp[j-o1]=max(dp[j]+o2,dp[j-o1]);
}
for(int j=n;j>=o1;j--)
{
dp1[j]=max(dp1[j-o1]+o2,dp1[j]) ;
}
}
}
//dp1更符合题意
sort(dp,dp+n+1);
cout<<dp1[n];
}
signed main() {
ll t = 1;
//cin >> t;
while (t--) {
solve();
}
}