[ACM]【模板/揹包DP】洛谷P1833 櫻花

傳送門
題意:有n種物品,每種拿一個都消耗TiT_i。有的只能拿一個,有的最多拿aia_i個,有的可以拿無數個(每種物品可拿PiP_i次)。每種物品的價值是cic_i,揹包容量是TT,求能獲得的最大價值。
圖

思路:

這題就是01揹包+多重揹包+完全揹包。

代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=10000;
int dp[1003];//前:第幾種物品 後:所裝多少 
int t[maxn+2],c[maxn+2],p[maxn+2];
int m;//全局變量:總時間(揹包容量) 
void completepack(int i,int cost,int weight){
	for(int j=0;j<=m;j++){
		if(j>=cost)dp[j]=max(dp[j],dp[j-cost]+weight);
	}
}
void zeroonepack(int i,int cost,int weight){
	for(int j=m;j>=0;j--){
		if(j>=cost)
		dp[j]=max(dp[j],dp[j-cost]+weight);
	}
}
void multiplepack(int i,int cost,int weight,int amount){
	if(cost*amount>=m){
		completepack(i,cost,weight);
		return;
	}
	int k=1;
	while(k<amount){
		zeroonepack(i,k*cost,k*weight);
		amount-=k;
		k*=2;
	}
	zeroonepack(i,amount*cost,amount*weight);
} 
int main(){
	int h1,m1,h2,m2,n;
	scanf("%d:%d %d:%d %d",&h1,&m1,&h2,&m2,&n);
	for(int i=1;i<=n;i++)scanf("%d%d%d",&t[i],&c[i],&p[i]);
	int mx=m2-m1;
	int hx=(h2-h1)*60;
	if(mx<0)hx=(h2-h1-1)*60;
	if(mx<0)mx=60-m1+m2;
	m=hx+mx;
	for(int i=1;i<=n;i++){
		if(p[i]==0)completepack(i,t[i],c[i]);
		else multiplepack(i,t[i],c[i],p[i]);
	}
	printf("%d\n",dp[m]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章