2738:Two Ends
概要
N(<1000)個の数列が与えられる。プレイヤー二人は交互に数列の両端どちらかの数字をとる。取った数字の合計値がスコアになる。後手の戦略が貪欲法であるとき、先手は後手よりどれだけ高いスコアをとれるか求める問題。
dp[iターンまで終了][残っている数列の左はどこか]でDPする。最後の処理に引っかかった。
static int ns[1001]; static int dp[1001][1002]; int main(){ int cnt=0, i, j, n; while(n = readint(), n){ REP(i,n)REP(j,n+1) dp[i][j] = -(1<<30); REP(i,n) ns[i] = readint(); dp[0][0] = 0; REP(i,(n>>1)){ REP(j,n)if(dp[i][j] > -(1<<30)){ int l = j, r = j + (n-2*i) - 1; if(ns[l+1] < ns[r]) dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j]+ns[l]-ns[r]); else dp[i+1][j+2] = max(dp[i+1][j+2], dp[i][j]+ns[l]-ns[l+1]); if(ns[l] < ns[r-1]) dp[i+1][j] = max(dp[i+1][j], dp[i][j]+ns[r]-ns[r-1]); else dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j]+ns[r]-ns[l]); } } int ans = -(1<<30); REP(i,n+1) ans = max(ans, dp[n>>1][i]); printf("In game %d, the greedy strategy might lose by as many as %d points.\n",++cnt, ans); } return 0; }