设 fif_ifi 表示剩余 iii 个石头时最多能拿的石头数量。
如果现在先手拿的是 aka_kak ,则还会剩下 i−aki-a_ki−ak 个石头,所以对方也只能拿 fi−akf_{i-a_k}fi−ak。还剩 i−fi−aki-f_{i-a_k}i−fi−ak,所以动态转移方程为:
fi=max(i−fi−ak) f_i=\max(i-f_{i-a_k})fi=max(i−fi−ak)
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,a[1000005],dp[1000005];
signed main()
{
cin>>n>>k;
for(register int i=1;i<=k;i++)
{
cin>>a[i];
}
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=k;j++)
{
if(i<a[j])//防止数组越界
{
break;
}
dp[i]=max(dp[i],i-dp[i-a[j]]);//根据动态转移方程
}
}
cout<<dp[n];
return 0;
}