设 f i f_i fi 表示剩余 i i i 个石头时最多能拿的石头数量。
如果现在先手拿的是
a
k
a_k
ak ,则还会剩下
i
−
a
k
i-a_k
i−ak 个石头,所以对方也只能拿
f
i
−
a
k
f_{i-a_k}
fi−ak。还剩
i
−
f
i
−
a
k
i-f_{i-a_k}
i−fi−ak,所以动态转移方程为:
f
i
=
max
(
i
−
f
i
−
a
k
)
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;
}