09-03 HDU_Steps3.3 各種揹包 HDU1114 HDU1171 HDU2191 HDU2955 HDU3496 HDU2546 HDU1203 HDU3466

HDU_STEPS3.3 主要是揹包問題


3.3.1 HDU1114 Piggy-Bank 完全揹包,要正好裝滿

#include <cstdio>
#include <string.h>
using namespace std;
int e,f,n;
int d[10005];
int p[505],w[505];
int main(){
	int cas;
	scanf("%d",&cas);
	while(cas--){
		scanf("%d%d",&e,&f);
		e=f-e;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%d%d",&p[i],&w[i]);
		
		//DP
		for(int i=1;i<=e;i++)d[i]=1e9;
		d[0]=0;
		for(int i=1;i<=n;i++){
			for(int j=w[i];j<=e;j++){
				if(d[j-w[i]]+p[i]<d[j])d[j]=d[j-w[i]]+p[i];		
			}	
		} 
		
		if(d[e]==1e9)printf("This is impossible.\n");
		else printf("The minimum amount of money in the piggy-bank is %d.\n",d[e]);
	}

	return 0;	
} 

3.3.2 HDU1171 Big Event in HDU 

多重揹包,每種物品個數有限制,用一個數組標記該值是否可達

最後從中間像兩邊掃描,先找到的值爲A和B中的一個

#include <cstdio>
#include <string.h>
using namespace std;
int n,tot; 
int v[55],m[55];
bool d[250005]; 
int main(){
	while(scanf("%d",&n)&&n>=0){
		int tot=0;
		for(int i=1;i<=n;i++){
			scanf("%d%d",&v[i],&m[i]); 
			tot+=v[i]*m[i];
		}
		
		//多重揹包 每種物品數目固定 DP 
		memset(d,0,sizeof d);
		d[0]=true;
		for(int i=1;i<=n;i++){
			for(int k=1;k<=m[i];k++){
				for(int j=tot;j>=v[i];j--){
					if(d[j-v[i]])d[j]=true;		
				}	
			}	
		}	
		//輸出答案 
		int ind=0;
		for(int i=tot/2,j=tot/2;;i++,j--){
			if(d[i]){ind=i;break;}
			if(d[j]){ind=j;break;}	
		}
		if(ind<tot-ind)ind=tot-ind;
		printf("%d %d\n",ind,tot-ind);
	} 
	return 0;	
}

3.3.3 HDU2191 悼念512汶川地震

多重揹包,跟新某一點時選擇價值更大的組合

		memset(d,-1,sizeof d);
		d[0]=0;
		for(int i=1;i<=m;i++){
			for(int j=1;j<=c[i];j++){
				for(int k=n;k>=p[i];k--){
					if(d[k-p[i]]!=-1&&d[k-p[i]]+h[i]>d[k]){
						d[k]=d[k-p[i]]+h[i];	
					}
				}	
			}
		}

3.3.4 HDU2955 Robberies 

題目看了半天才看懂,就是求小偷最多能偷幾個銀行,DP使該點不被捉的概率最大

假如偷了N個銀行,被捉概率是p1,p2..pn ,則不被捉的概率是(1-p1)(1-p2)...(1-pn)

#include <cstdio>
using namespace std;
int cas,mi[101],n,tot;
double pi[101],p;

double d[10000];
int main(){
	scanf("%d",&cas);
	while(cas--){
		for(int i=0;i<=10000;i++)d[i]=0;
		tot=0;
		d[0]=1; 
		
		scanf("%lf%d",&p,&n);
		for(int i=1;i<=n;i++){
			scanf("%d%lf",&mi[i],&pi[i]);
			tot+=mi[i];	
		}
		//揹包 轉換爲乘法 使同一個點不被捉的概率最大 
		for(int i=1;i<=n;i++){
			for(int j=tot;j>=mi[i];j--){
				if(d[j]<d[j-mi[i]]*(1-pi[i]))d[j]=d[j-mi[i]]*(1-pi[i]);
			}
		}
		
		for(int i=tot;i>=0;i--){
			if(d[i]>=1-p){printf("%d\n",i);break;}	
		}
	}
	
	return 0;	
}

3.3.5 HDU3496 Watch the Movie

二維揹包,揹包中的物品個數有限制

狀態表示爲d[n][m],n爲使用物品的個數,m爲揹包中物品的個數

注意循環的方向,要保證d[n][m]中有m件物品,最後d[N][M]即爲所求

#include <cstdio>
#include <string>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;

int cas,n,m,l; 
int w[105],v[105],d[105][1005];
int main(){
	scanf("%d",&cas);
	while(cas--){
		scanf("%d%d%d",&n,&m,&l);
		for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&v[i]);
		
		//DP
		memset(d,-1,sizeof d);
		d[0][0]=0;
		for(int i=1;i<=n;i++){
			for(int j=m;j>=1;j--){//注意方向,很重要 
				for(int k=l;k>=w[i];k--){
					if(d[j-1][k-w[i]]!=-1)d[j][k]=max(d[j][k],d[j-1][k-w[i]]+v[i]);	
				}	
			}	
		}
		
		int r=0;
		for(int i=1;i<=l;i++)r=max(r,d[m][i]);
		printf("%d\n",r); 
			
	}

    //system("pause");
    return 0;
}

3.3.6 HDU2546 飯卡

一開始直接揹包DP,當飯卡餘額大於5元時纔跟新,最後最大值和卡上的錢的差就是餘額..但是提交WA了

比如卡上8元,兩種商品7元和2元,如果按照7,2的順序跟新,2元的商品就不會去買了,因爲買了7元的商品後餘額就只有1元了..加上一個排序就過了,價值大的商品的後買,這樣可以保證卡上最後餘額最少.

#include <cstdio>
#include <string.h>
#include <algorithm> 
using namespace std;
int main(){
	int n,p[1005],m,d[1100];
	while(scanf("%d",&n),n){
		for(int i=1;i<=n;i++)scanf("%d",&p[i]);
		sort(p+1,p+1+n);
		scanf("%d",&m);
		
		memset(d,0,sizeof d);
		d[0]=1;
		for(int i=1;i<=n;i++){
			//放寬50因爲可能是負的 
			for(int j=m+55;j>=p[i];j--){
				//餘額大於5元纔可 
				if(j-p[i]<=m-5&&d[j-p[i]])d[j]=1;	
			}
		}
		for(int i=m+55;i>=0;i--){
			if(d[i]==1){
				printf("%d\n",m-i);
				break;	
			}	
		}
	}
	return 0;	
}

3.3.7 HDU1203 I NEED A OFFER 

這題與3.3.4類似,揹包的對象也是概率,是不能拿到Offer的概率最小p=(1-a1)(1-a2)...(1-an)


3.3.8 HDU3466 Proud Merchants

帶有貪心性質的揹包,按Q-P的值排序後再揹包即可



發佈了91 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章