1. 程式人生 > >Coins(多重揹包)

Coins(多重揹包)

Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hibix opened purse and found there were some coins. He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.

You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.
Input The input contains several test cases. The first line of each test case contains two integers n(1 ≤ n ≤ 100),m(m ≤ 100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test case is followed by two zeros. Output For each test case output the answer on a single line. Sample Input
3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0
Sample Output
8
4
題意:有n種貨幣和手錶價格為m,單位貨幣的價值有val[i],單位貨幣的數量有vol[i],。求解帶哪些 貨幣val*貨幣數量vol 可將手錶買回且身上的錢總價值最大題解:注意時間上的優化,為避免超時,將多重揹包問題分成完全揹包和01揹包問題,01揹包再用二進位制優化
#include<iostream> 
#include<algorithm>
#include<string.h>
#define INF 0x3f3f3f3f
using namespace std;
//手錶價格 
int m; 
//單位貨幣的價值
int val[1005];
//單位貨幣的數量
int vol[1005];
int dp[100005];
void Zero(int cost){
	for(int i=m;i>=cost;i--)
		dp[i]=max(dp[i],dp[i-cost]+cost);
}
//val*vol>>m,硬幣可以無限使用,可以使用完全揹包 
void Com(int cost){
	for(int i=cost;i<=m;i++)
		dp[i]=max(dp[i],dp[i-cost]+cost);
}
//拆分vol,價格係數k*vol組成新硬幣 
void mul(int val,int vol){
	if(val*vol>=m)
		Com(val);
	else{
		int k=1;
		while(k<=vol){
			Zero(k*val);
			vol-=k;
			k*=2;
		}
		Zero(vol*val);
	}
}
int main(){
	//貨幣的種類 
	int n;
	while(cin>>n>>m,(n||m)){
		for(int i=1;i<=n;i++)
			cin>>val[i];
		for(int i=1;i<=n;i++)
			cin>>vol[i];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<=m;i++)
			dp[i]=-INF;
		dp[0]=0;
		for(int i=1;i<=n;i++)
			mul(val[i],vol[i]);
		int ans=0;
		for(int i=1;i<=m;i++)
			if(dp[i]>0)
				ans++;
		cout<<ans<<endl;
	}
	return 0;
}