现在的位置: 首页 > 综合 > 正文

ural 1928 Another ecology problem 博弈dp

2018年04月25日 ⁄ 综合 ⁄ 共 854字 ⁄ 字号 评论关闭

题解:两个公司从教育部轮流申请资金,如果库中钱充足的话那么就会拨给这个公司,如果一旦库中没有钱那么停止,如果申请的钱多余库中的那么教育部长会

         把手中的m元钱给他之后申请结束,开始库中有n元钱,每个公司每次申请资金的范围是[1 , k],问先手的公司最多能得到多少钱,在得到最多钱的情况下

         能让对手得到最少的钱数。

题解:开始是博弈的想法,枚举每个人决策的平衡态,莫名其妙的过了,队友搞了dp,找到一组反例证明我的博弈想法是有错误的,dp应该是正解。

          dp[ i ][ 0 ]代表的是当前剩余 i 元钱先手申请到的最多的钱,dp[ i ][ 1 ]代表剩余 i 元钱先手得到的最多钱时对手得到的最少的钱,转移方程具体见代码。


Sure原创,转载请注明出处

#include <iostream>
#include <cstdio>
#include <memory.h>
#define MAX(a , b) ((a) > (b) ? (a) : (b))
using namespace std;
const int maxn = 10002;
int dp[maxn][2];
int m,n,k;

void solve()
{
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            if(j <= i)
            {
                if(dp[i-j][1] + j > dp[i][0] || (dp[i-j][1] + j == dp[i][0] && dp[i][1] > dp[i-j][0]))
                {
                    dp[i][0] = dp[i-j][1] + j;
                    dp[i][1] = dp[i-j][0];
                }
            }
            else
            {
                if(dp[i][0] < m || (dp[i][0] == m && dp[i][1] > 0))
                {
                    dp[i][0] = m;
                    dp[i][1] = 0;
                }
                break;
            }
        }
    }
    printf("%d %d\n",dp[n][0],dp[n][1]);
    return;
}

int main()
{
    while(~scanf("%d %d %d",&n,&m,&k))
    {
        solve();
    }
    return 0;
}

抱歉!评论已关闭.