POJ 1276 Cash Machine(dp+多重背包)

Cash MachinePOJ - 1276

cash N n1 D1 n2 D2 ... nN DN
最大面值和cash,面值数N,面值Di有ni张

对给定数据,最大不超过cash,可以凑多少钱

分析:

一种物品——一个面值

物品质量——面值

不超过最大质量——不超过最大面值

物品价值——面值

最大价值——最大面值和

注意这里面值既是质量也是价值, 就是一个简单的多重背包问题

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<stack>   
#include<set>  
#include<bitset>  
#include<list>

#define UP(i,x,y) for(int i=x;i<=y;i++)  
#define DOWN(i,x,y) for(int i=x;i>=y;i--)  
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a) 
#define ll long long  
#define INF 0x3f3f3f3f  
#define EXP 1e-10  
#define lowbit(x) (x&-x)
 
using namespace std;
int n[15],d[15];
int dp[100010];
int main(){
	int cash,num;
	while(cin>>cash>>num){
		MEM(n,0);MEM(d,0);MEM(dp,0);
		for(int i=1;i<=num;i++){
			cin>>n[i]>>d[i];
		}
		for(int i=1;i<=num;i++){
			if(n[i]*d[i]>=cash){
				//cout<<"hi"<<endl;
				for(int j=d[i];j<=cash;j++){
					if(dp[j]<dp[j-d[i]]+d[i]){
						dp[j]=dp[j-d[i]]+d[i];
					}
					//cout<<j<<' '<<dp[j]<<endl;
				}
			}
			else{
				int k=1,t=n[i];
				while(t-k>=0){
					t-=k;
					for(int j=cash;j>=k*d[i];j--){
						if(dp[j]<dp[j-k*d[i]]+k*d[i]){
							dp[j]=dp[j-k*d[i]]+k*d[i];
						}
					}
					k*=2;
				}
				for(int j=cash;j>=t*d[i];j--){
					if(dp[j]<dp[j-t*d[i]]+t*d[i]){
						dp[j]=dp[j-t*d[i]]+t*d[i];
					}
				}
			}
			//cout<<dp[cash]<<endl;
		}
		cout<<dp[cash]<<endl;
	}	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41333528/article/details/80383755