NYOJ 625 笨蛋的難題(二)
阿新 • • 發佈:2019-02-12
剛開始以為是博弈方面的問題,浪費了不少時間。
這道題的解法有點像動態規劃,同時也有點貪心的意思
總體思想是倒推,分解成多個子問題,從後往前算...first記錄從當前位置向後先取的最大值,last記錄從當前位置向後取的最大值..v[i]為當前處理的工資..
核心部分如下:
first=0;
last=0;
for(i=t-1;i>=0;i--)
if(v[i]+last>=first) //如果成立,則取v[i],否則不取
{
tem=last;
last=first;
first=v[i]+tem;
}
因為總是要自己取得最大值,所以,在判斷是不是取v[i]時,只需判斷是取v[i]能獲得的錢多,還是放棄v[i],取v[i+1]獲得的錢多(有可能v[i+1]也放棄);
如果要取v[i]的話,必定有v[i]+last>=first成立(等號不能去),在這裡,last,first均是上一個子問題的結果,即從i+1開始,先取能獲得的最大值,後取能獲得的最大值。所以,v[i]+last即為當前子問題中的先取獲得的最大值,first為當前子問題中後取能獲得的最大值(放棄v[i])。
然後,將first賦值為v[i]+last(上一個子問題中的last), last賦值為上一個子問題中的first。
#include <stdio.h> int main() { int v[125]; int t; int tem; int sum; int i; int first,last; while(scanf("%d",&t)!=EOF) { sum=0; for (i=0;i<t;i++) { scanf("%d",&v[i]); sum+=v[i]; } first=0; last=0; for(i=t-1;i>=0;i--) if(v[i]+last>=first) //如果成立,則取v[i],否則不取 { tem=last; last=first; first=v[i]+tem; } printf("%d %d %d\n",first,last,sum-first-last); } return 0; }