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;
}