1. 程式人生 > >Easy Game LightOJ - 1031

Easy Game LightOJ - 1031

pac pro 自己的 ets algorithm col 個數 遊戲 esp

Easy Game LightOJ - 1031

題意:A和B玩一個遊戲,A先手。規則是兩人輪流在當前數列的任意一端取走任意個數(但不能兩端都取),然後把這些數的和加到自己的得分上,直到數列被取完。如果兩人都采取最優策略,那麽A比B最多能多得多少分?

sum(l,r)表示原數列l到r範圍內的數之和。ans[l][r]表示要取完l到r區間的數,先手的人可以得到的比對手多的最大得分。

那麽,如果l==r,也就是只有一個,那麽他必須取這一個,ans[l][r]=sum(l,r)。

否則,他可以選擇在左側取走第l個到第i個,那麽自己得到sum(l,i),之後對手按照最優策略能比自己多ans[i+1][r]分,那麽ans[l][r]=max{sum(l,i)-ans[i+1][r]}。他也可以選擇在右側取走第i個到第r個,那麽自己得到sum(i,r),之後對手按照最優策略比自己多ans[l][i-1],那麽ans[l][r]=max{sum(i,r)-ans[l][i-1]}。他也可以選擇全部選完,那麽ans[l][r]=sum(l,r)。最後答案就是上述三種中最大的一種。時間復雜度$O(n^3)$。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int sum[110],ans[110][110],a[110],T,TT,n;
 6 int getsum(int l,int r)
 7 {
 8     return sum[r]-sum[l-1];
 9 }
10 int get(int l,int r)
11 {
12     if(ans[l][r])    return ans[l][r];
13 int i,maxans=getsum(l,r); 14 for(i=l;i<r;i++) 15 maxans=max(maxans,getsum(l,i)-get(i+1,r)); 16 for(i=r;i>l;i--) 17 maxans=max(maxans,getsum(i,r)-get(l,i-1)); 18 return ans[l][r]=maxans; 19 } 20 int main() 21 { 22 int i; 23 scanf("%d",&T);
24 for(TT=1;TT<=T;TT++) 25 { 26 memset(a,0,sizeof(a)); 27 memset(sum,0,sizeof(sum)); 28 memset(ans,0,sizeof(ans)); 29 scanf("%d",&n); 30 for(i=1;i<=n;i++) 31 scanf("%d",&a[i]); 32 for(i=1;i<=n;i++) 33 sum[i]=sum[i-1]+a[i]; 34 printf("Case %d: %d\n",TT,get(1,n)); 35 } 36 return 0; 37 }

Easy Game LightOJ - 1031