zoukankan      html  css  js  c++  java
  • UVA10891

    /*
    题意:n 个数 AB两个人轮流从左或右端取连续的数,
    每个人都按最优策略取,A先取,问最后A 比 B 多多少 。
    区间DP。 
    用f[i][j]表示区间 i-j 能取的数的总和是多少, 
    如果从左端取,f[i][i+k]=max(f[i][i+k], (sum[i+k]-sum[i-1])-f[i][j]); 其中j∈[i,i+k) 。 
    则右端, f[i][i+k]=max(f[i][i+k], (sum[i+k]-sum[i-1])-f[j][j+k]); 其中j∈[i+1,i+k] .
    再与取一整段比较取最优。
    辣么,A比B多 f[1][n]- (f[1][n]-sum[n]) 即 2 * f[1][n] - sum[n]
    */ 
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int sum[110],a[110];
    int f[110][110];
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF && n)
        {
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum[i]=sum[i-1]+a[i];
            }    
            int s=0;
            memset(f,-0x3f,sizeof(f));    
            for(int i=1;i<=n;i++)
                f[i][i]=a[i];
            for(int k=1;k<n;k++)
                for(int i=0;i+k<=n;i++)                                                                                                                                                                                                                                                    
                {
                    s=sum[i+k]-sum[i-1];  
                    for(int j=i;j<i+k;j++)                 
                        f[i][i+k] = max(f[i][i+k], s-f[i][j]);
                    for(int j=i+1;j<=i+k;j++)  
                        f[i][i+k] = max(f[i][i+k], s-f[j][i+k])    ;
                    f[i][i+k] = max(s,f[i][i+k]);                         
                }
             printf("%d
    ", 2 * f[1][n] - sum[n]);
        }
        return 0;
    }
  • 相关阅读:
    为上次写的框架加了一个辅助功能
    复制文件夹下所有文件
    进制之间的相互转换
    c# 修改appConfig文件节点
    GUID
    太悲哀了
    poj2411 Mondriaan's Dream
    poj3311 Hie with the Pie
    HDU3001 Travelling
    luogu p2622关灯问题II
  • 原文地址:https://www.cnblogs.com/ember/p/4905697.html
Copyright © 2011-2022 走看看