zoukankan      html  css  js  c++  java
  • 硬币问题

    有 n 种硬币,面值分别为V1,V2,V3...Vn ,每种都有无限多。给定非负整数 S ,可以选用多少个硬币,使得面值之和恰好为 S ?输出硬币数目的最小值和最大值。

    记忆化搜索:

    #include <iostream>
    #include <cstring>
    using namespace std;
    #define MAX 20005
    int n, dp[MAX], vis[MAX], v[MAX];
    
    int dp_max(int s)
    {
    	if(vis[s]) return dp[s];
    	vis[s] = 1;
    	int &ans = dp[s];
    	ans = -1 << 30;
    	for(int i = 1; i <= n; i++)
    	{
    		if(s >= v[i])
    		{
    			ans = max(ans, dp_max(s - v[i]) + 1);
    		}
    	}
    	return ans;
    }
    
    int dp_min(int s)
    {
    	if(vis[s]) return dp[s];
    	vis[s] = 1;
    	int &ans = dp[s];
    	ans = 1 << 30;
    	for(int i = 1; i <= n; i++)
    	{
    		if(s >= v[i])
    		{
    			ans = min(ans, dp_min(s - v[i]) + 1);
    		}
    	}
    	return ans;
    }
    
    void print_ans(int s)
    {
    	for(int i = 1; i <=n; i++)
    	{
    		if(s >= v[i] && dp[s] == dp[s - v[i]] + 1)
    		{
    			cout << i << " ";
    			print_ans(s - v[i]);
    			break;
    		}
    	}
    }
    
    int main()
    {
    	freopen("in.txt", "r", stdin);
    	int s;
    	cin >> n >> s;
    	for(int i = 1; i <= n; i++)
    	{
    		cin >> v[i];
    	}
    	memset(dp, 0, sizeof(dp));
    	memset(vis, 0, sizeof(vis));
    	vis[0] = 1;
    	cout << "max = " << dp_max(s) << endl;
    	print_ans(s);
    	cout << endl;
    
    	memset(dp, 0, sizeof(dp));
    	memset(vis, 0, sizeof(vis));
    	vis[0] = 1;
    	cout << "min = " << dp_min(s) << endl;
    	print_ans(s);
    	cout << endl;
    	return 0;
    }

    递推实现:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define MAX 1000
    #define INF (1 << 30)
    int	Max[MAX], Min[MAX], v[MAX];
    int n;
    
    void print_ans(int *dp, int s)
    {
    	for(int i = 1; i <= n; i++)
    	{
    		if(s >= v[i] && dp[s] == dp[s - v[i]] + 1)
    		{
    			cout << i << " ";
    			print_ans(dp, s - v[i]);
    			break;
    		}
    	}
    }
    
    int main()
    {
    	freopen("in.txt", "r", stdin);
    	int s;
    	cin >> n >> s;
    	for(int i = 1; i <= n; i++)
    	{
    		cin >> v[i];
    	}
    	Min[0] = Max[0] = 0;
    	for(int i = 1; i <= s; i++)
    	{
    		Min[i] = INF;
    		Max[i] = -INF;
    	}
    	for(int i = 1; i <= s; i++)
    	{
    		for(int j = 1; j <= n; j++)
    		{
    			if(i >= v[j])
    			{
    				Min[i] = min(Min[i], Min[i - v[j]] + 1);
    				Max[i] = max(Max[i], Max[i - v[j]] + 1);
    			}
    		}
    	}
    	cout << "min = " << Min[s] << endl;
    	print_ans(Min, s);
    	cout << endl;
    
    	cout << "max = " << Max[s] << endl;
    	print_ans(Max, s);
    	cout << endl;
    	return 0;
    }


  • 相关阅读:
    flex布局
    媒体查询
    transform详细解释
    读取long类型数据
    Oracle中快速清空当前用户的所有表数据
    没有表头的csv文件怎么导入Kettle
    Kettle性能调优汇总
    oralce中特殊字符的查询
    数据的单值、多值、派生、简单、复合属性
    kettle学习
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5835143.html
Copyright © 2011-2022 走看看