时间:1s 空间:256M
题目描述:
有 n 块蛋糕,小信和小红轮流吃。有一个长度为 m 的序列,小信和小红每次可以选择序列中的一个数 a,并吃掉 a 块蛋糕,选择的数必须小于当前蛋糕的块数。序列中必定会有 1,显然他们能把蛋糕全都吃完。
现在小信先开始吃,他们都想尽可能多吃蛋糕。若他们都足够聪明,最后小信能吃到多少块蛋糕?
输入格式:
第一行包含两个整数 n,m。
第二行包含 m 个整数 ai 。保证a1=1,ai−1<ai,ak≤n。
输出格式:
输出一个整数表示答案。
样例输入:
10 3 1 3 4
样例输出:
6
约定与提示:
对于100%的数据,1≤n≤1e4,1≤m≤100。
对于样例,小信先吃3块蛋糕,接着小红无论吃1块还是3块还是4块蛋糕,小信至少都能再吃3块蛋糕,因此小红会吃4块蛋糕,小信吃掉剩下的3块,所以小信总共吃了6块蛋糕。
题意:
n块蛋糕,有m种吃法,小明先吃,小红和小明都是最优解,问小明最后能吃几块
思路:
dp题,我们定义两个数组,一个数组记录还剩i块蛋糕,从小信先开始,小信吃能吃几块蛋糕,还有一个数组记录还剩i块蛋糕,小红先吃能吃几块蛋糕,当我们要推a[i]时状态转移方程为总共蛋糕数去减小信所有吃蛋糕的可能,推b[i]也是用这般的状态转移方程。
代码:
#include<bits/stdc++.h>
using namespace std;
long long a[10005];
long long b[10005];
int s[10005];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>s[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i>=s[j]){
a[i]=max(a[i],i-b[i-s[j]]);
b[i]=max(a[i],i-a[i-s[j]]);
}
}
}
cout<<a[n];
}