码迷,mamicode.com
首页 > 其他好文 > 详细

2014-2015 ACM-ICPC, Asia Tokyo Regional Contest-I Sweet War

时间:2020-10-24 11:41:35      阅读:24      评论:0      收藏:0      [点我收藏+]

标签:type   namespace   ace   for   class   i+1   icp   efi   eof   

[2014-2015 ACM-ICPC, Asia Tokyo Regional Contest-I Sweet War]


网上想找篇这题的题解还挺费劲的...
首先看起来是博弈实则用dp来做,虽然用dp但还是有点博弈的感觉。首先对于一块巧克力,体力值大的人具有话语权,因为两个人轮流放弃的话,最后一定是体力少的被迫选那块巧克力,这个题中有关体力值的数据又都非常大,所以考虑两人体力值的差值。

我们用两个dp数组来体现两个人博弈的关系。\(FA[i][j]\)表示当前A在选第i个巧克力,想要选到第n个时A获得美味度为j,A需要与B体力值的最小差值(A表示第一个人,B表示第二个人)。\(FB[i][j]\)表示当前B在选第i个巧克力,想要选到第n个时A获得美味度为j,A需要与B体力值的最小差值。由于两人的竞争关系,A想要让FA尽可能小(不费吹灰之力),B想让FB尽可能大(让A难受)。同时有初始值\(FA[n+1][0]=FB[n+1][0]=-INF\)(表示体力值差多少都行)

第一个转移方程:

\(FA[i][j] = min(FB[i+1][max(j-s[i], 0LL)]-r[i], max(FA[i+1][j]+1+r[i], 1LL))\)

第一项表示假如A选择吃掉这块巧克力,值就等于轮到B选第n+1块巧克力时的状态(由于FA第二维表示i开始选到n要获得美味度j,吃了第i块获得s[i]那么第i+1块开始,只要吃够j-s[i]就行了,当然吃够就行了,所以j-s[i]不能小于0。因为会获得体力值r[i],所以目前状态就是下一个状态减去r[i])。第二项表示如果A没吃,B吃了,那么一方面A要损失1点体力值,同时B要增加体力值r[i],A目前的状态就会是\(FA[i+1][j]+1+r[i]\),当然这个值要大于1,不然他就没有不吃的资格。

第二个转移方程:

\(FB[i][j] = max(FA[i+1][j]+r[i], min(FA[i][j]-1, -1LL))\)

思路和第一个方程差不多,想明白还挺费劲的,max体现了B想让A尽可能费劲。

最后遍历一遍\(FA[1][j](sum >=j>=0)\), j从大到小遍历,如果FA的值小于A与B的差值,答案就是j


代码
#include <bits/stdc++.h>
typedef long long ll;
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll FA[200][200], FB[200][200];
ll r[200], s[200]; 
int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    int n, a, b;
    int sum = 0;
    cin >> n >> a >> b;
    for(int i=1; i<=n; i++){
        cin >> r[i] >> s[i];
        sum += s[i];
    }
    memset(FA, 0x3f, sizeof(FA));
    memset(FB, 0x3f, sizeof(FB));
    FA[n+1][0] = -INF;
    FB[n+1][0] = -INF;
    for(int i=n; i>0; i--){
        for(int j=0; j<=sum; j++){
            FA[i][j] = min(FB[i+1][max(j-s[i], 0LL)]-r[i], max(FA[i+1][j]+1+r[i], 1LL));
            FB[i][j] = max(FA[i+1][j]+r[i], min(FA[i][j]-1, -1LL));
        }
    }
    int ans;
    for(int i=sum; i>=0; i--){
        if(FA[1][i]<=a-b){
            ans = i;
            break;
        }
    }
    cout << ans << " " << sum-ans << endl;
    return 0;
}

2014-2015 ACM-ICPC, Asia Tokyo Regional Contest-I Sweet War

标签:type   namespace   ace   for   class   i+1   icp   efi   eof   

原文地址:https://www.cnblogs.com/DinoMax/p/13861813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!