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 }
时间: 2024-11-08 09:35:16

Codeforces Round #436 (Div. 2) E. Fire的相关文章

Codeforces Round #436 (Div. 2)【A、B、C、D、E】

Codeforces Round #436 (Div. 2) 敲出一身冷汗...感觉自己宛如智障:( codeforces 864 A. Fair Game[水] 题意:已知n为偶数,有n张卡片,每张卡片上都写有一个数,两个人每人选一个数,每人可以拿的卡片必须写有是自己选的数,问能否选择两个数使得两个人每人拿的卡片数一样多并且能拿光卡片.[就是看输入是不是只有两种数字] //:第一遍我看成字符串包含有选的数字也能拿,,这样写着居然过了..水题水题.. 1 #include<cstdio> 2

Codeforces Round #436 (Div. 2) C. Bus

Codeforces Round #436 (Div. 2) C. Bus A bus moves along the coordinate line Ox from the point x = 0 to the point x = a. After starting from the point x = 0, it reaches the pointx = a, immediately turns back and then moves to the point x = 0. After re

Codeforces Round #436 (Div. 2) F Cities Excursions

题意是给你一个有向图,点n <= 3000, 边m <= 3000,从s到t的路径必须是最小字典序,q<=400000次询问,从s到t中路径第k个点是什么,否则输出-1. 7 7 51 22 31 33 44 55 34 61 4 22 6 11 7 31 3 21 3 5 解释下样例2-6. 2-6的路径为2-3-4-5-3-5-3...-5-6无限循环,所以可以当作这个路径不存在,所以为-1 1-3的路径为1-2-3 如果在线做复杂度肯定要高,把询问的边存储,枚举出发点离线解决 用v

【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!

题意:给你一个长度为n的数组,每个元素都在1~n之间,要你改变最少的元素,使得它变成一个1~n的排列.在保证改动最少的基础上,要求字典序最小. 预处理cnt数组,cnt[i]代表i在原序列中出现的次数.b数组,代表没有出现过的数是哪些.b数组的长度就是答案. b数组是从小到大排好的,然后for循环b数组,同时用一个指针p指着a数组的当前位置,最开始指向开头,如果cnt[a[p]]==1,就向后跳,否则再看 是否b[i]<a[p]或者a[p]这个数是否已经出现过了(用个hav数组表示a[p]是否已

[Codeforces] Round #436 (Div. 2)

1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 int n,cnt,ans,A,B; 6 int buck[500]; 7 8 int main(){ 9 scanf("%d",&n); 10 11 for(int i = 1;i <= n;i++){ 12 cin >> cnt; 13 if(!buck[cnt]){ 14 ans++; 15 if(

Codeforces Round #436 (Div. 2) B.Polycarp and Letters

因为难得又一次CF的比赛是非常清真的傍晚,超级少见啊 所以当然要打啦,于是rank:87,rating+=76,滞留在上紫的边缘 下面把几道觉得还不错的题目来总结一下 B.Polycarp and Letters Polycarp loves lowercase letters and dislikes uppercase ones. Once he got a string s consisting only of lowercase and uppercase Latin letters.

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我