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 }
  • 相关阅读:
    LVS NAT模式
    lvs部署-DR模式
    Lvs原理
    iOS判断UIScrollView的滚动方向
    Swift开发必备技巧:内存管理、weak和unowned
    Swift2.0异常处理
    Swift中的延迟加载(懒加载)
    Swift和OC混编时, 关于@objc的作用
    Swift函数的定义建议
    Swift隐式可选型简单介绍
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/11688278.html
Copyright © 2011-2022 走看看