• UVa 10891 Sum游戏


    https://vjudge.net/problem/UVA-10891

    题意:

    有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取。每次玩家只能从左端或者右端取任意数量个数,但不能两端都取。所有数都被取走后游戏结束,然后统计每个人取走的所有数之和,作为各自的得分。两个人采取的策略都是让自己的得分尽量高,并且两个人都足够聪明,求A的得分减去B的得分后的结果。

    思路:

    不管是轮到谁取数,都是在一个序列中从左边或右边开始取最大值。

    那么我们就令d【i】【j】表示先手在【i~j】序列中所能取到的最大值。

    状态转移时,枚举从左端开始取k个数和从右端开始取k个数即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13 typedef pair<int,int> pll;
    14 const int INF=0x3f3f3f3f;
    15 const int maxn=100+5;
    16 
    17 int n;
    18 int a[maxn];
    19 int sum[maxn];
    20 int vis[maxn][maxn];
    21 int d[maxn][maxn];
    22 
    23 int dp(int i,int j)
    24 {
    25     if(vis[i][j])  return d[i][j];
    26     vis[i][j]=1;
    27 
    28     int m=0;
    29     for(int k=i+1;k<=j;k++)  m=min(m,dp(k,j));
    30     for(int k=j-1;k>=i;k--)  m=min(m,dp(i,k));
    31     d[i][j]=sum[j]-sum[i-1]-m;
    32     return d[i][j];
    33 }
    34 
    35 int main()
    36 {
    37     //freopen("D:\input.txt","r",stdin);
    38     while(~scanf("%d",&n) && n)
    39     {
    40         sum[0]=0;
    41         for(int i=1;i<=n;i++)
    42         {
    43             scanf("%d",&a[i]);
    44             sum[i]=sum[i-1]+a[i];
    45         }
    46 
    47         memset(vis,0,sizeof(vis));
    48         printf("%d
    ",2*dp(1,n)-sum[n]);
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    mysql登录和连接 权限
    No package mysql-server available.
    rails开发demo(一)搭建环境
    chrome和搜狗浏览器的js问题
    setInterval setTimeout clearInterval
    几道面试题
    du df 查看文件和文件夹大小
    win7开启休眠功能
    ssh key scp命令 scp无密码传输
    dd 生成指定大小文件
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6920639.html
Copyright © 2020-2023  润新知