2017/9/26Codeforces E题
生活随笔
收集整理的這篇文章主要介紹了
2017/9/26Codeforces E题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2017/9/26Codeforces E題
我終于打了一場cf了,可惜我太蒟蒻,6題才出了4題,反思一下,訂正一下吧
E題面:http://codeforces.com/contest/864/problem/E
E題大意:
Polycarp家著火了,現在Polycarp要把一些東西救出來,每樣東西都有三個值ti(救出來所花的時間),di(物品被燒毀的時間,只有物品在被燒毀前救出來才有價值),pi(物品價值)
輸入:一個N(1≤N≤100),之后N行每行三個數ti(1≤ti≤20),di(1≤di≤2000),pi(1≤pi≤20)
輸出:第一行是最大救出的價值,第二行輸出被救出的物品數量,第三行按被救順序輸出每個物品的編號(編號為物品輸入順序),若有多種方案則輸出一種
樣例輸入1
3
3 7 4
2 6 5
3 7 6
樣例輸出1
11
2
2 3
樣例輸入2
2
5 6 1
3 3 5
樣例輸出2
1
1
1
題目不難,想一想O(n^2)能過,剛開始看想個背包,然后呢發現,好像就是啊,只是物品會被燒毀,那么就大力DP一發吧
既然是想O(n^2)的轉移,那么一維轉移物品一維用作時間
f[i]表示到第i的時間所獲取的價值最大值
狀態轉移
是不是感覺很easy?
然而,要怎么樣放才能保證轉移不因為被燒毀時間而掛掉呢
由于我偷懶,所以在考場上我按di-ti排序,然后成功WA
為什么呢?因為有這樣的情況:
p1=8 , d1=10,p1=10
p2=1 , d2=4 , p2=10
答案是20我的程序輸出10
那怎么辦呢?
直接按di排序就好啦
為什么呢?
假設兩個物品a,b能同時救出,那么一定滿足這個情況
若a被摧毀時間比b早
若a被摧毀時間比b晚
(因為保證能同時存在所以b被摧毀的時間一定在a、b被救出來之后)
然后就好啦
放一下代碼 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline void read(int&x) {char cu=getchar();x=0;bool fla=0;while(cu<'0'||cu>'9'){if(cu=='-')fla=1;cu=getchar();}while('0'<=cu&&cu<='9')x=x*10+cu-'0',cu=getchar();if(fla)x=-x; } void printe(const int x) {if(x>=10)printe(x/10);putchar(x%10+'0'); } inline void print(const int x) {if(x<0)putchar('-'),printe(-x);else printe(x); } int N; struct things {int t,d,p,ended,id;//在ended時刻之前救該物品才有效,id即編號 }t[101]; int cmp(things x,things y) {return x.d<y.d; } int dp[2001],from[2001][2001],ans=-1,wz; int main() {memset(dp,-1,sizeof(dp));read(N);for(int i=1;i<=N;i++)read(t[i].t),read(t[i].d),read(t[i].p),t[i].id=i;sort(t+1,t+N+1,cmp);//排序,尤其注意 for(int i=1;i<=N;i++)t[i].ended=t[i].d-t[i].t;//算出ended dp[0]=0;for(int i=1;i<=N;i++){if(t[i].ended<=0)continue;//特判 for(int j=t[i].ended-1;j>=0;j--){if(dp[j]==-1)continue;//特判 if(dp[j]+t[i].p>dp[j+t[i].t]){dp[j+t[i].t]=dp[j]+t[i].p;//轉移 memcpy(from[j+t[i].t],from[j],sizeof(from[j+t[i].t])); from[j+t[i].t][++from[j+t[i].t][0]]=t[i].id;//更新 }}}for(int i=0;i<=2000;i++)//找出答案 if(dp[i]>ans){ans=dp[i];wz=i;}print(ans);putchar('\n');print(from[wz][0]);putchar('\n');if(from[wz][0]!=0){print(from[wz][1]);for(int i=2;i<=from[wz][0];i++)putchar(' '),print(from[wz][i]);}return 0; } 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的2017/9/26Codeforces E题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10任务计划+PowerShell
- 下一篇: 整数判重、大整数Hash