Hdu 6199 Shenyang Network Competition --- gems (DP), hdu --- gems
Question Link
Problem DescriptionNow there are n gems, each of which has its own value. Alice and Bob play a game with these n gems.
They place the gems in a row and decide to take turns to take gems from left to right.
Alice goes first and takes 1 or 2 gems from the left. after that, on each turn a player can take k or k + 1 gems if the other player takes k gems in the previous turn. the game ends when there are no gems left or the current player can't take k or k + 1 gems.
Your task is to determine the difference between the total value of gems Alice took and Bob took. Assume both players play optimally. Alice wants to maximize the difference while Bob wants to minimize it.
InputThe first line contains an integer T (1 ≤ T ≤ 10), the number of the test cases.
For each test case:
The first line contains a numbers n (1 ≤ n ≤20000 );
The second line contains n numbers: V1, V2... Vn. (− 100000 ≤ Vi ≤ 100000)
OutputFor each test case, print a single number in a line: the difference between the total value of gems Alice took and the total value of gems Bob took.
Sample Input131 3 2
Sample Output4. There are now n pieces of gemstone in a row. The value is v [1 ~ N]. Now Alice and Bob take turns from left to right to get the gemstone. Alice takes the first and can take 1 or 2, then Bob takes ...... If the previous person has k, the current person can only take k or k + 1 gemstone. (Condition of the end. If the first person has k gems, and the remaining k is less than k, the person does not need to take them. If the remaining k gems are k, the person must take k ), now Alice and Bob both want to get as much GEM value as possible than the other party, and ask Alice for the value and-Bob's value and maximum value? Idea: Dynamic Planning, defining dp [I] [k] [j], k values 0 and 1 (0 indicates Alice fetch, 1 indicates Bob fetch ), I indicates the I-th gem (1 <= I <= 20000), and j indicates that j-th gemstone (1 <= j <= 200, because one person can get a maximum of 200 pieces of gemstone at a time, dp [I] [k] [j] indicates that I ~ When n pieces of gemstone (pushed forward from the back), the value difference between the k-person from I and the k-person from the right consecutively; in addition, the space limit of this question is relatively tight, therefore, you need to use a rolling array. Set the first dimension to 205. The Code is as follows:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const int N=20005;const int M=203;int sum[N];int dp[M][2][205];int main(){ int T; cin>>T; while(T--) { sum[0]=0; memset(dp,0,sizeof(dp)); int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&sum[i]),sum[i]+=sum[i-1]; for(int i=n;i>=1;i--) { for(int j=1;j<M;j++) { if(i+j-1>n) break; int tmp=sum[i+j-1]-sum[i-1], t; if(i+j+j<=n) t=min(dp[(i+j)%M][1][j],dp[(i+j)%M][1][j+1]); else if(i+j+j-1<=n) t=dp[(i+j)%M][1][j]; else t=0; dp[i%M][0][j]=tmp+t; if(i+j+j<=n) t=max(dp[(i+j)%M][0][j],dp[(i+j)%M][0][j+1]); else if(i+j+j-1<=n) t=dp[(i+j)%M][0][j]; else t=0; dp[i%M][1][j]=t-tmp; } } int ans; if(n>=2) ans=max(dp[1][0][1],dp[1][0][2]); else ans=dp[1][0][1]; printf("%d\n",ans); } return 0;}