5790:Ball Stacking
問題文
https://icpcarchive.ecs.baylor.edu/external/57/5790.pdf
図のようにコストがついた玉がいくつか与えられる。ある玉を取り除くとそのコスト分だけ得点がもらえる。その玉の上に玉が無ければ取り除くことができる。得点を最大化せよ。
与えられる玉を回転させたように配列に入れる。Sample Input 1なら、
3 3 -8 7 5 2 -2 -8 9 3
というように使う。この配列で、左から右に累積和をとる。そして、今みている玉を取らずに左に移動するのと、玉を取って下にいくのをメモ化再帰でやった。
#include<iostream> #include<vector> #include<algorithm> #define INF (1LL<<62) using namespace std; typedef long long ll; int g[1010][1010],n; ll memo[1010][1010]; ll rec(int h,int w){ if(h==n)return 0; if(memo[h][w]>-INF)return memo[h][w]; ll res=0; if(w>0)res=max(res,rec(h,w-1)); if(w<n-h)res=max(res,rec(h+1,w)+g[h][w]); return memo[h][w]=res; } int main(void){ while(cin >> n,n){ fill(g[0],g[1010],0); for(int i=0;i<n;i++) for(int j=0;j<=i;j++)cin >> g[j][i-j]; for(int i=0;i<n;i++) for(int j=0;j<n-i;j++)g[i][j+1]+=g[i][j]; fill(memo[0],memo[1010],-INF); cout << rec(0,n-1) << endl; } return 0; }