Description
Input
Output
Sample Input
735 3 4 125 6 5 3 350
633 4 500 30 6 100 1 5 0 1
735 0
0 3 10 100 10 50 10 10
Sample Output
735
630
0
0
题意:给你n种类型的硬币 分别给出每种硬币的数量和面额 现在问你最大能组成的面额(小于等于给定的面额) 是多少?
思路:标准的多重背包 二进制优化即可
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<time.h> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1000000007; int a[15]; int value[15]; int dp[100007]; int main(){ ios::sync_with_stdio(false); int mo; while(cin>>mo){ memset(dp,0,sizeof(dp)); int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]>>value[i]; dp[0]=1; for(int i=1;i<=n;i++){ int temp=a[i]; int now=1; while(1){ if(temp>now){ temp-=now; for(int j=mo;j>=now*value[i];j--) if(dp[j-now*value[i]]) dp[j]=1; now*=2; }else{ for(int j=mo;j>=temp*value[i];j--) if(dp[j-temp*value[i]]) dp[j]=1; break; } } } int ans=0; for(int i=mo;i>=0;i--){ if(dp[i]){ ans=i; break; } } cout<<ans<<endl; } return 0; }
原文:https://www.cnblogs.com/wmj6/p/10685331.html