Fire CodeForces - 864E(01背包)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lidengdengter/article/details/89890594

题目链接

拿每件物品耗时t ,价值为w 当总时超过d则不能拿,问最大价值以及取物号(物品标号)。

01背包问题,用dp[i][j]代表拿第i个物品用时j的价值,则

拿:dp[i][j] = max( dp[i-1][j] , dp[i-1][j-t] + w ) ;

不拿:dp[i][j] = dp[i-1][j] 。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105;

struct node{
	int id;
	int t,d,w;
}p[N];
int dp[105][2005];
bool vis[105][2005];
vector<int>ans;

bool cmp1(node a,node b){
	return a.d<b.d;
}

int main(){
	int n,maxd;
	while(~scanf("%d",&n)){
		ans.clear();
		memset(dp,0,sizeof(dp));
		memset(vis,false,sizeof(vis));
		maxd=0;
		for(int i=1;i<=n;i++){
			scanf("%d%d%d",&p[i].t,&p[i].d,&p[i].w);
			p[i].id=i;
			maxd=max(maxd,p[i].d);
		}
		
		sort(p+1,p+1+n,cmp1);
		
		int pos;
		for(int i=1;i<=n;i++){
			pos=0;
			for(int j=0;j<=maxd;j++){
				if(j>=p[i].t&&j<p[i].d&&dp[i-1][j]<dp[i-1][j-p[i].t]+p[i].w){
					dp[i][j]=dp[i-1][j-p[i].t]+p[i].w;
					vis[i][j]=true;
				}
				else
					dp[i][j]=dp[i-1][j];
					
				if(dp[i][pos]<dp[i][j])  //one best time
					pos=j;
			}
		}
		
		printf("%d\n",dp[n][pos]);
		for(int i=n;i>0;i--)
			if(vis[i][pos]){  //save
				ans.push_back(p[i].id);
				pos-=p[i].t;
			}
			
		printf("%d\n",ans.size());
		for(int i=ans.size()-1;i>=0;i--)
			printf("%d%c",ans[i],i==0?'\n':' ');
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/lidengdengter/article/details/89890594