洛谷纸币问题123

题目链接:

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();
	    }
	}

猜你喜欢

转载自blog.csdn.net/song0789/article/details/143469753