zoukankan      html  css  js  c++  java
  • TZOJ 2965 A Coin Game(DP)

    描述

    Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game called Xoinc for them.

    Initially a stack of N (5 ≤ N ≤ 2,000) coins sits on the ground; coin i from the top has integer value Ci (1 ≤ Ci ≤ 100,000).

    The first player starts the game by taking the top one or two coins (C1 and maybe C2) from the stack. If the first player takes just the top coin, the second player may take the following one or two coins in the next turn. If the first player takes two coins then the second player may take the top one, two, three or four coins from the stack. In each turn, the current player must take at least one coin and at most two times the amount of coins last taken by the opposing player. The game is over when there are no more coins to take.

    Afterwards, they can use the value of the coins they have taken from the stack to buy treats from FJ, so naturally, their purpose in the game is to maximize the total value of the coins they take. Assuming the second player plays optimally to maximize his own winnings, what is the highest total value that the first player can have when the game is over?

    输入

    * Line 1: A single integer: N

    * Lines 2..N+1: Line i+1 contains a single integer: Ci

    输出

    * Line 1: A single integer representing the maximum value that can be made by the first player.

    样例输入

    5
    1
    3
    1
    7
    2

    样例输出

    9

    题意

    有两个人n枚硬币,A先手可以取1-2个,B最多可以取A*2个,问A的最大总价值。

    题解

    dp[i][j]表示剩下1-i,上个人取了j枚的最大总价值。

    那么答案显然是dp[n][1],表示剩下1-n,上个人取了1枚(虚的),那么先手就可以取1枚或者2枚。

    O(n^3)的转移dp[i][j]=max(sum[i]-dp[i-k][k])(1<=k<=2*j)。

    易得dp[i][j-1]=max(sum[i]-dp[i-k][k])(1<=k<=2*j-2)。

    两个相差sum[i]-dp[i-2*j][2*j]和sum[i]-dp[i-(2*j-1)][2*j-1]。

    所以O(n^3)的转移可以优化一层变成O(n^2)。

    dp[i][j]=(dp[i][j-1]或者max(sum[i]-dp[i-k][k])(2*j-1<=k<=2*j))。

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n,sum[2005],c[2005],dp[2005][2005];
     5 int main()
     6 {
     7     scanf("%d",&n);
     8     for(int i=n;i>=1;i--)scanf("%d",&c[i]);
     9     for(int i=1;i<=n;i++)sum[i]=sum[i-1]+c[i];
    10     for(int i=1;i<=n;i++)
    11     {
    12         for(int j=1;j<=n;j++)
    13         {
    14             dp[i][j]=dp[i][j-1];
    15             int k=2*j-1;
    16             if(k<=i)dp[i][j]=max(dp[i][j],sum[i]-dp[i-k][k]);
    17             k++;
    18             if(k<=i)dp[i][j]=max(dp[i][j],sum[i]-dp[i-k][k]);
    19         }
    20         for(int j=1;j<=n;j++)
    21             printf("%d ",dp[i][j]);
    22         printf("
    ");
    23     }
    24         
    25     printf("%d
    ",dp[n][1]);
    26     return 0;
    27 }
  • 相关阅读:
    十分钟构建双十一交互分析大盘
    数字IT基础-数据采集总线
    阿里云文件存储(NAS)助力业务系统承载双十一尖峰流量
    如何在网络视听行业建一扇内容安全大门?
    Frost & Sullivan权威报告:阿里云再次领跑云WAF大中华区市场
    赋能时空云计算,阿里云数据库时空引擎Ganos上线
    点播转码相关常见问题及排查方式
    《边缘云计算技术及标准化白皮书》
    内存性能的正确解读
    《倡议书——节约用电,从我做起》
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/11688278.html
Copyright © 2011-2022 走看看