uva10891 - Game of Sum

来源:互联网 发布:php动态加密系统 编辑:程序博客网 时间:2024/05/13 17:33

题意:
给一个序列,AB两人比赛,每人每次只能从左或从右取任意连续数,都足够聪明,极力想让自己赢,A先开始取,让你求A和B都取最优策略时,A-B的得分结果。
思路:
初写dp没多久,式子怎么也推不出来,看了题解,原来是这样的:
让sum[i]表示前i个数总和,要求A-B即求 A - (sum[n]- A),即求2*A-sum[n]。
求A的话,让dp[i][j]表示A在第i~j个数中取到的值,则dp[1][n]即为最终要求得的A,有dp[i][j]=(sum[j]-sum[i-1]) - 区间i~j的最小值(m).

代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 105;int arr[N],sum[N],dp[N][N],visit[N][N],n;int dfs(int i,int j) {    if (visit[i][j])        return dp[i][j];    visit[i][j] = 1;    int k, m = 0;    for (k = i + 1; k <= j; k++)        m = min(m, dfs(k, j));    for (k = i; k < j; k++)        m = min(m, dfs(i, k));    dp[i][j] = sum[j] - sum[i - 1] - m;    return dp[i][j];}int main() {    int n;    while (~scanf("%d", &n) && n) {        int i;        memset(visit, 0, sizeof(visit));        for (i = 1; i <= n; i++) {            scanf("%d", &arr[i]);            sum[i] = sum[i - 1] + arr[i];        }        printf("%d\n", 2 * dfs(1, n) - sum[n]);    }    return 0;}
0 0
原创粉丝点击