【Tai_mount】 算法学习 - 动态规划 -luoguP1049 [NOIP2001 普及组] 装箱问题
这道题其实非常非常简单,但是我中间好莫名其妙的搞了半天,晕。
最终是发现了两种写法:
求和
//https://www.luogu.com.cn/problem/P1049
#include<iostream>
#include<cstring>
using namespace std;
const int N=37,M=20007;
int vol,n,v[N],dp[M];
void input(){
cin>>vol>>n;
for(int i=1;i<=n;i++){
cin>>v[i];
}
}
void dpfun(){
for(int i=1;i<=n;i++){
for(int j=vol;j>0;j--){
if(j<v[i]) continue;
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
}
}
void output(){
cout<<vol-dp[vol];
}
int main(){
input();
dpfun();
output();
return 0;
}
这种方法就是,我们认为每个物品的价值就是它的体积。
就这么简单,是吧,我&@!%&#&¥!&%@&#*半天没想出来。
【Tai_mount菜死了】
算剩余
这方法是我一开始想的,但是万万妹想到啊,转移方程给写错了。
//https://www.luogu.com.cn/problem/P1049
#include<iostream>
#include<cstring>
using namespace std;
const int N=37,M=20007;
int vol,n,v[N],dp[M];
void input(){
cin>>vol>>n;
for(int i=1;i<=n;i++){
cin>>v[i];
}
}
void init(){
for(int i=1;i<=vol;i++){
dp[i]=i;
}
}
void dpfun(){
for(int i=1;i<=n;i++){
for(int j=vol;j>0;j--){
if(j<v[i]) continue;
dp[j]=min(dp[j],dp[j-v[i]]);
}
}
}
void output(){
cout<<dp[vol];
}
int main(){
input();
init();
dpfun();
output();
return 0;
}
要注意有初始化,就是dp[i]赋值i
这里的dp[j]算的事剩下的体积(也就是你要输出的那个东西)
转移方程:dp[j]=min(dp[j],dp[j-v[i]])
你可以利用dp[j]=j-sum[j]来推,这里的sum[j]就是第一种方法里的dp[j]
也可以直接算,不买就是dp[j],买就是dp[j-v[i]]+(j-(j-v[i]))-v[i],后面化简就只剩dp[i-v[i]]
@#¥()*了,我怎么推半天推错了
所以请一定动笔写

浙公网安备 33010602011771号