题目
求按照一定的顺序得到的最大得分。
分析
普通的01背包是不可以的,因为它有顺序,所以用贪心的思想,把顺序确定出来,再用01背包。
状态转移方程:
f
[
j
]
=
max
(
f
[
j
]
,
f
[
j
−
w
[
i
]
]
+
c
[
i
]
∗
j
)
f[j]=\max(f[j],f[j-w[i]]+c[i]*j)
f[j]=max(f[j],f[j−w[i]]+c[i]∗j)
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
struct sh{int w,c;}sc[3001];
int n,m,ans,f[10001];
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
bool cmp(sh x,sh y){return x.w*y.c>x.c*y.w;}//以乘积进行贪心
int main(){
n=in(); m=in();
for (int i=1;i<=n;i++) sc[i].w=in(),sc[i].c=in();
stable_sort(sc+1,sc+1+n,cmp);
for (int i=1;i<=n;i++)
for (int j=m;j>=sc[i].w;j--){
f[j]=max(f[j],f[j-sc[i].w]+sc[i].c*j);//背包
if (i==n) ans=max(ans,f[j]);
}
printf("%d",ans); return 0;
}