ABC 270 D - Stones(博弈DP)

https://atcoder.jp/contests/abc270/tasks/abc270_d

题目大意:

给定我们总共n个石子,我们每次拿的数量都必须是数组a中的一个,高桥先手,青木后手。

问我们高桥可以拿到的最大数量的石子数是多少?
Sample Input 1 
10 2
1 4
Sample Output 1 
5

Sample Input 2  
11 4
1 2 3 6
Sample Output 2  
8

详解见代码注释

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL INF=1e9;
const LL N=5000200,M=2002;
LL a[N],f[N];
//f[i]表示石子总个数为i时先手能拿到的最多石子数
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        LL n,k;
        cin>>n>>k;
        for(int i=1;i<=k;i++)
        {
            cin>>a[i];
        }
        f[0]=0;
        for(LL i=1;i<=n;i++)//依次枚举石子数
        {
            for(LL j=1;j<=k;j++)//假设我们选了第j个操作
            {
                if(i>=a[j])//而且当前是可取的话
                {
                    //那么我们将多获得a[j]个石头
                    //轮到对面的时候,对面肯定是会让自己最多
                    //所以对面肯定拿的石头数量是f[i-a[j]]
                    //所以我们能够拿到的石头数量就是a[j]+(i-a[j])-f[i-a[j]]

                    //f[i]=max(f[i],a[j]+(i-a[j])-f[i-a[j]]);
                    f[i]=max(f[i],i-f[i-a[j]]);
                }
            }
        }
        cout<<f[n]<<endl;
    }
    return 0;
}
posted @ 2022-11-09 21:13  Vijurria  阅读(15)  评论(0编辑  收藏  举报