您的位置:首页 > 其它

codeforces #436 - E. Fire (记录路径dp)

2017-10-10 22:09 369 查看
有一些东西,抢救的时间为t,时间到达d会消失,价值为p,

问在最后一个东西销毁之前所能抢救的最大物品价值是多少,并输出抢救的个数及序号。

题解:dp
表示前n秒内所能抢救物品的最大价值。

排序枚举时间

其实我记录这题的价值在于如何记录路径,学习一下,应该是可以通用的吧

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <vector>
#define mod  1000000007
#define INF  0x3f3f3f3f
#define fuck() (cout << "----------------------------------------" << endl)
using namespace std;
const int maxn = 2000000 + 5;
struct node
{
int t, d, p;
int id;
bool operator < (const node & q) const
{
return d < q.d;
}
}pp[maxn];
int vis[105][2005];
int dp[maxn];
int b[maxn];
int main()
{
int n;
while(scanf("%d",&n) == 1 && n)
{
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&pp[i].t, &pp[i].d, &pp[i].p);
pp[i].id = i;
}
sort(pp+1, pp+1+n);
for(int i=1; i<=n; i++)
{
int t = pp[i].t;
for(int j=pp[i].d-1; j>=t; j--)
{
if(dp[j] < dp[j-t] + pp[i].p)
{
dp[j] = dp[j-t] + pp[i].p;
vis[i][j] = 1;
}
}
}
int ans = 0;
int cnt = 0;
for(int i=1; i<pp
.d; i++) if(dp[i] > dp[ans]) ans = i;
printf("%d\n",dp[ans]);
for(int i=n; i>=1; i--)
if(vis[i][ans])
{
b[cnt++] = pp[i].id;
ans -= pp[i].t;
}
printf("%d\n",cnt);
for(int i=cnt-1; i>=0; i--)
{
if(i == cnt-1) printf("%d",b[i]);
else printf(" %d",b[i]);
}
printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: