zoukankan      html  css  js  c++  java
  • UVa10891 Game of Sum

    给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能从一端选取。两人都采用最优策略,A先手,问A和B各自得到数字的和的差值最大为多少?

    区间DP

    F[i][j]表示区间i~j内A能得到的最大数字和。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=110;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int a[mxn];
    17 int sum[mxn],L[mxn][mxn],R[mxn][mxn];
    18 int f[mxn][mxn];
    19 int n;
    20 void solve(){
    21     int i,j;
    22     for(i=1;i<=n;i++){
    23         f[i][i]=L[i][i]=R[i][i]=a[i];
    24     }
    25     for(int st=2;st<=n;st++){
    26         for(i=1;i<=n-st+1;i++){
    27             j=i+st-1;
    28             f[i][j]=sum[j]-sum[i-1]-min(min(L[i+1][j],0),R[i][j-1]);
    29             L[i][j]=min(f[i][j],L[i+1][j]);
    30             R[i][j]=min(f[i][j],R[i][j-1]);
    31         }        
    32     }
    33     printf("%d
    ",f[1][n]-(sum[n]-f[1][n]));
    34     return;
    35 }
    36 int main(){
    37     int i,j;
    38     while(scanf("%d",&n) && n){
    39         for(i=1;i<=n;i++)a[i]=read();
    40         memset(f,0,sizeof f);
    41         memset(L,0x3f,sizeof L);
    42         memset(R,0x3f,sizeof R);
    43         for(i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
    44         solve();
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    点分治
    SG函数入门
    博弈论入门
    YY的gcd
    整除分块
    gcd约分函数的应用
    C++ 模拟类型(提高)
    C++数论题(博弈论)
    C++(gcd)的应用2。
    C++暴力约分(gcd).
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6575454.html
Copyright © 2011-2022 走看看