P2871 【[USACO07DEC]手链Charm Bracelet】
传送门
题目描述
Bessie has gone to the mall’s jewelry store and spies a charm bracelet.Of course, she’d like to fill it with the best charms possible from the N (1 ≤ N ≤ 3,402) available charms.Each charm i in the supplied list has a weight Wi (1 ≤ Wi ≤ 400), a ‘desirability’ factor Di (1 ≤ Di ≤ 100), and can be used at most once.Bessie can only support a charm bracelet whose weight is no more than M (1 ≤ M ≤ 12,880).
Given that weight limit as a constraint and a list of the charms with their weights and desirability rating, deduce the maximum possible sum of ratings.
有 N N 件物品和一个容量为的背包。第 i i 件物品的重量是,价值是 w[i] w [ i ] 。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
输入输出格式
输入格式:
Line 1: Two space-separated integers: N and M
Lines 2..N+1: Line i+1 describes charm i with two space-separated integers: Wi and Di
第一行:物品个数N和背包大小 M M
第二行至第行:第i个物品的重量 C[i] C [ i ] 和价值 W[i] W [ i ]
输出格式:
- Line 1: A single integer that is the greatest sum of charm desirabilities that can be achieved given the weight constraints
输出一行最大价值。
输入输出样例
输入样例#1: 复制
4 4
1 1
2 2
3 3
2 2
输出样例#1: 复制
23 23
小菜鸡最近比较多做 动态规划,动规,dp 的题。
今天,小菜鸡就发一道水题(做了三次才
AC
A
C
)。
这道题是一道红题,难度为 入门难度 。
讲了这么多废话,来说说重点。
这道题属于典型的 背包 的 动态规划,动规,dp。
那我们看看是什么类型的 背包。
显然是一道基础的01背包。
但要注意数据范围(小菜鸡被坑了一次,好不开心)。
这道01背包是带有价值的。
开讲思路:
1.注意一下数组大小
2.虽带有价值但不是完全背包,千万不要打错是01背包。
3.输出是f[v]最大价值。
上代码:
//最近小菜鸡改了下代码风格,为了省一行代码变成了丑丑风格
#include<cstdio>//调用 scanf和printf 的库
#include<cstring>//调用 memset 的库
#define ll long long//定义long long类型习惯了
const ll mx=50010;//注意数据范围
ll n,v;
ll c[mx],w[mx],f[mx];
//定义变量和数组
ll max(ll x,ll y) { return x>y?x:y; }//比较大小函数
//一切准备就绪
int main(){
memset(f,0,sizeof(f));//将f[]初始值为0
scanf("%lld %lld",&n,&v);
for(ll i=1;i<=n;i++)scanf("%lld %lld",&c[i],&w[i]);
//完美的输入
for(ll i=1;i<=n;i++){//做01背包
for(ll j=v;j>=c[i];j--)f[j]=max(f[j],f[j-c[i]]+w[i]);//更新
}
printf("%lld",f[v]);//输出f[v]最大价值
return 0;//bye bye下次再见
}