链接:https://ac.nowcoder.com/acm/problem/21186
来源:牛客网
题目描述
Rabbit通过了上次boss的考核,现在她又遇到了一个问题。
Rabbit接到了K个任务,每个任务她可以自由选择用i天去完成(1≤ i≤ N)。刁钻的boss想让Rabbit恰好用W天完成所有任务。
已知Rabbit用i天完成一个任务能让boss获得的满意度为vi(因为完成任务的质量不同),她想知道在满足boss要求的情况下能让boss获得的总满意度最大是多少。
输入描述
第一行三个整数N,K,W。
第二行N个整数vi,vi表示用i天完成一个任务能让boss获得的满意度。
输出描述
输出Rabbit在满足boss要求的情况下能让boss获得的总满意度最大是多少。
分析
怪丢人的,,,背包问题居然翻车了
首先我们可以确定这是个背包问题,而且是个完全恰好背包,因为不仅同一件物品可以用很多次,并且要让这个背包装满
所以我们需要让所有的状态都由背包为空,即f[0]转移而来,最终的状态是装满了整个背包,也就是f[w]
最后,题目要求每件工作都需要做完,所以我们可以将每件任务都放入背包中,即每个任务都放入背包,然后剩下的天数当成物品进行枚举,跑一下完全背包的板子即可
代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 2010,M = 4010;
int a[N],f[M];
int n,k,w;
int main(){
memset(f,-0x3f,sizeof f);
f[0] = 0;
scanf("%d%d%d",&n,&k,&w);
scanf("%d",&a[0]);
for(int i = 1;i < n;i++){
scanf("%d",&a[i]);
a[i] -= a[0];
}
w -= k;
for(int i = 1;i <=n;i++)
for(int j = i;j <= w;j++)
f[j] = max(f[j],f[j - i] + a[i]);
printf("%d\n",f[w] + k * a[0]);
}