题目背景
众所周知,西西艾弗岛上的机器人喜欢吃苹果。
题目描述
据饲养员小 P 介绍:
- 机器人一天最多可以吃 m 个苹果。
- 一天内通过吃苹果获得的快乐值具体为:A0,A1,⋯,Am;如果某一天饲养员共投喂机器人 ii 个苹果,则这一天机器人获得的快乐值为 Ai。
- 特别地 A0=0,快乐值并不会凭空产生。
现在小 P 有 n 个苹果,试帮助小 P 计算:向机器人投喂这 n 个苹果能获得的最大快乐值收益。
输入格式
从标准输入读入数据。
输入共两行。
第一行包含两个整数 n 和 m,分别表示苹果总数和每天最大投喂量。
第二行依次包含 m 个整数 A1,A2,⋯,Am,表示一天内投喂不同苹果数的收益。
输出格式
输出到标准输出。
输出仅一个整数,表示投喂全部 n 个苹果能获得的最大收益。
样例1输入
10 5
1 3 5 3 1
样例1输出
16
样例1解释
一种最优投喂方案为:投喂四天,每天分别投喂 3、3、1 和 3 个苹果。
如该样例所示,收益序列 A 不一定单调递增,即一天内吃较多苹果可能反而获得较小快乐值。
样例2输入
4 3
1 60 100
样例2输出
120
样例2解释
一种最优投喂方案为:投喂两天,每天投喂 2 个苹果。
子任务
测试数据说明:
- 40% 的数据满足:n ≤ 50 且 m = 5;
- 另外 40% 的数据满足:n = 60 且 m = 6;
- 所有测试数据满足:0 < n ≤ 10^4、0 < m ≤ 100,且 0 ≤ A_i ≤ 10^5。
题解
这道题本质就是一个完全背包,直接套板子就行。背包容量为n,物品价值为Ai,物品体积为i。
贴一个完全背包的模板(使用滚动数组优化):
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1010;
int f[N];
int v[N],w[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++)
for(int j=v[i];j<=m;j++)
f[j]=max(f[j],f[j-v[i]]+w[i]);
cout<<f[m];
return 0;
}
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int n,m;
int a[N],f[N];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>a[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
f[i]=max(f[i],f[i-j]+a[j]);
}
}
cout<<f[n];
}