Coins (hdu 2844)多重背包

今天重新学习了多重背包,为选拔赛做准备。

这道题学习了大神键盘上的舞者的模板,感谢~

本题就是简单的多重背包,先判断将该硬币化为完全背包还是01背包处理,01背包利用二进制化简。

题目求的是一共能表示多少种price,这里答案用dp[ i ] == i 判断,原因如下:

这道题全部初始化为零,也就是不装满求最大,硬币代表的价值为背包容量,同时也是背包里的值。当dp[ i ]即最大容量为i时,装i是最大的,而当dp[ i ]的值不等于i,则说明没装满,也就是说会有  dp[ dp[ i ] ] = dp[ i ],所以每一种price都会在dp[ price ]中出现,故这样求结果。


#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
int n,m;
int v[110];
int t[110];
int dp[100010];
void MP(int value,int space,int num);
int main(){

	scanf("%d%d",&n,&m);
	while(n||m){
		for(int i=0;i<n;i++){
			scanf("%d",&v[i]);
		}
		for(int i=0;i<n;i++){
			scanf("%d",&t[i]);
		}
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++){
			MP(v[i],v[i],t[i]);
		}
		int sum = 0;
		for(int i=1;i<=m;i++){
			if(i==dp[i])	sum++;
		} 
		printf("%d\n",sum);
		scanf("%d%d",&n,&m);
	} 
	return 0;
}
//完全背包 
void CP(int value,int space){
	for(int i=value;i<=m;i++){
		dp[i] = max(dp[i],dp[i-value] + space);
	} 
}
//01背包 
void ZOP(int value,int space){
	for(int i=m;i>=value;i--){
		dp[i] = max(dp[i],dp[i-value] + space);
	}
}
//多重背包判断转化 
void MP(int value,int space,int num){
	if(num*value>=m){//当总价值超过背包容量 
		CP(value,space);
	}
	else{//二进制转化 
		int k=1;
		while(k<=num){
			ZOP(value*k,space*k);
			num-=k;
			k*=2;
		}
		ZOP(value*num,space*num);
	}
}


你可能感兴趣的:(dp,多重背包)