Game of Sum ----区间dp----dfs写法

This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at a time. He can take as many consecutive numbers as he wants during his time. The game ends when all numbers are taken from the array by the players. The point of each player is calculated by the summation of the numbers, which he has taken. Each player tries to achieve more points from other. If both players play optimally and player A starts the game then how much more point can player A get than player B?
Input
The input consists of a number of cases. Each case starts with a line specifying the integer n (0 < n ≤ 100), the number of elements in the array. After that, n numbers are given for the game. Input is terminated by a line where n = 0.
Output
For each test case, print a number, which represents the maximum difference that the first player obtained after playing this game optimally.
Sample Input
4 4 -10 -20 7 4 1 2 3 4 0
Sample Output
7 10

这道题的题意就是两个人可以从左边或者右边进行选取一段连续区间,然后每个人都是最优的,A先手B后手,然后问如此取完后,两人的差值是多少。

思路:由于一个人取多少石子也要看之后的影响,所以最终的大问题一定也是由小问题慢慢累积得到的。所以这种情形就考虑到可以用区间dp。在这里我的方法用的是dfs写的。

其中,我们要想办法在一段段小连续区间最优值之间找一个最小的,意思就是说,我想从右边开始取,然后我要从左边找一段连续的,然后如果这个最小值还大于0的话,那么说明我从右边取所有的,这样才会最大。如果最小值是小于0的,那么显而易见,我用这段的总和减去从左边开始取的这一段的最小值就会使我拿到的最优。这样就是一种递推的过程。

显然,初值dp[i][i]=a[i];

思路参考:

Game of Sum ----区间dp----dfs写法_第1张图片


代码:

#include
using namespace std;
int vis[110][110];
int dp[110][110];
int sum[110];
int a[110];
int dfs(int begin,int end)
{
    if(vis[begin][end]==1)
        return dp[begin][end];
    int maxx=;
    vis[begin][end]=1;
    for(int i=begin+1;i<=end;i++)
    {
        minn=min(minn,dfs(i,end));
    }
    for(int i=begin;i<=end-1;i++)
    {
        minn=min(minn,dfs(begin,i));
    }
    dp[begin][end]=sum[end]-sum[begin-1]-minn;
    return dp[begin][end];
}
int main()
{
    int n;
    while(scanf("%d",&n))
    {
        if(n==0)
            break;
        sum[0]=0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        int lala=dfs(1,n);
        cout<

你可能感兴趣的:(DP_区间dp)