HDU 6199 gems gems gems (2017瀋陽網絡賽)

比賽的時候想出了DP的遞推式,感覺好像可以做但又不自信,後來又想錯了dp[i][j],第二維其實只有200多。(又急着走結果就否定掉自己思路了)
遞推式類似dp1[i][j] = max (dp2[i-j][j],dp2[i-j][j-1]) + pre[i]-pre[j]這樣,dp2同理,因爲是第一個人先動,所以最後會是dp1的最優值。但是這道題內存卡的小,看了網上大神的題解,有通過指針,還有滾動數組的做法,於是順便學了個新姿勢。
#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
using namespace std;
typedef long long ll;
#define maxn 20010
const int maxn2 = 255+10;
int dp[2][maxn2][205];
int v[maxn];
#define MOD 255
int pre[maxn];
int main()
{
    int t;
    int i;
    int n;
    scanf ("%d",&t);
    while (t--){
        memset (dp,0,sizeof(dp));
        scanf ("%d",&n);
        for (i=1;i<=n;i++){
            scanf ("%d",&v[i]);
            pre[i]=pre[i-1]+v[i] ;
        }
        int k = sqrt(2.0*n)+1;
        int j;
        for (i=n;i;i--)
            for (j=k;j;j--){
                if (i+j<=n){
                    dp[0][i&MOD][j]=pre[i+j-1]-pre[i-1]+max(dp[1][(i+j+1)&MOD][j+1]+v[i+j],dp[1][(i+j)&MOD][j]);
                    dp[1][i&MOD][j]=pre[i-1]-pre[i+j-1]+min(dp[0][(i+j+1)&MOD][j+1]-v[i+j],dp[0][(i+j)&MOD][j]);
                }
                else if (i+j-1<=n){
                    dp[0][i&MOD][j]=pre[i+j-1]-pre[i-1]+dp[1][(i+j)&MOD][j];
                    dp[1][i&MOD][j]=-pre[i+j-1]+pre[i-1]+dp[0][(i+j)&MOD][j];
                }
            }
        printf("%d\n", dp[0][1][1]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章