Codeforces Round #436 (Div. 2) E. Fire
题意:给你n个需要救得东西,每个东西给出t,d,p,表示需要花费t时间,在d时间之前,价值为p,问救出最多价值,并把每个东西序号输出,比如 3 3 4 ,这就无法救出
思路:dp,dp[i][j]表示救出第i个花费j时间救出最大价值,dp[i][j]=max(dp[i][j],dp[i-1][j-a[i][d]]+a[i].val)(j<=2000),再记录个g[i][j]表示第i个东西在j时间是救出来的,然后倒推
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=110; 5 6 int dp[N][4002]; 7 int g[N][4002]; 8 struct node{ 9 int t,d,val,id; 10 }a[N]; 11 int n; 12 13 bool cmp(node p,node q){ 14 return p.d<q.d; 15 } 16 17 void slove(int x,int y,int s){ 18 19 if(x==0){ 20 cout<<s<<endl;return ; 21 } 22 else { 23 if(!g[x][y]){ 24 slove(x-1,y,s); 25 } 26 else { 27 28 slove(x-1,y-a[x].t,s+1); 29 30 cout<<a[x].id<<" "; 31 } 32 } 33 } 34 int main(){ 35 scanf("%d",&n); 36 for(int i=1;i<=n;i++){ 37 scanf("%d%d%d",&a[i].t,&a[i].d,&a[i].val); 38 a[i].id=i; 39 } 40 sort(a+1,a+1+n,cmp); 41 for(int i=1;i<=n;i++){ 42 for(int j=0;j<=2000;j++){ 43 dp[i][j]=dp[i-1][j]; 44 g[i][j]=0; 45 if(a[i].t<=j&&a[i].d>j){ 46 if(dp[i-1][j-a[i].t]+a[i].val>dp[i][j]){ 47 g[i][j]=1; 48 dp[i][j]=dp[i-1][j-a[i].t]+a[i].val; 49 } 50 } 51 } 52 } 53 int Max=0; 54 int xx=0,yy=0; 55 for(int i=1;i<=n;i++) 56 for(int j=1;j<=2001;j++){ 57 if(Max<dp[i][j]){ 58 xx=i;yy=j; 59 Max=dp[i][j]; 60 } 61 } 62 // cout<<xx<<" "<<yy<<" "<<g[xx][yy]<<endl; 63 cout<<Max<<endl; 64 slove(xx,yy,0); 65 }