HDU 1114——Piggy-Bank
这道题是直接套用完全背包问题的一道题目。刚开始做的时候给数组dp赋初值是-1,但是这道题是一道求最小值的问题,所以初值不能赋-1。本来思路是-1作为一个标记,如果是-1就进行特殊处理,可是真正在dp中间,处理有些麻烦。所以dp的初值还是赋成最大比较方便。代码如下:
#include<iostream>
using namespace std;
const int maxn=100000000;
__int64 P[505];
int W[505];
__int64 dp[10005];
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int E,F;
cin>>E>>F;
int n;
cin>>n;
for(int i=0;i<n;++i){
cin>>P[i]>>W[i];
}
int pw=F-E;
if(pw==0){cout<<"The minimum amount of money in the piggy-bank is "<<0<<'.'<<endl;continue;}
for(int i=0;i<=pw;++i){
dp[i]=maxn;
}
dp[W[0]]=P[0];
for(int i=W[0]+W[0];i<=pw;){
dp[i]=dp[i-W[0]]+P[0];
i+=W[0];
}
for(int i=1;i<n;++i){
for(int j=W[i];j<=pw;++j){
if(j==W[i]&&dp[j]==maxn){
dp[j]=P[i];
}
else if(j==W[i]){
dp[j]=min(dp[j],P[i]);
}
if(dp[j-W[i]]==maxn)continue;
dp[j]=min(dp[j],dp[j-W[i]]+P[i]);
}
}
if(dp[pw]==maxn)cout<<"This is impossible."<<endl;
else cout<<"The minimum amount of money in the piggy-bank is "<<dp[pw]<<"."<<endl;
}
return 0;
}
如果把代码中所有的maxn改为-1作为标记,那么存在一个问题。
假设到达第i层的时候,该硬币重量为5,价值为10。假设dp[j-5]不是-1,但是dp[j]是-1,那么存在一个问题,在执行语句dp[j]=min(dp[j],dp[j-W[i]]+P[i]);时,dp[j]永远是-1,不可能变大。
在想明白这个问题以后,尝试讲maxn改为-1,也运行通过了,代码如下:
#include<iostream>
using namespace std;
const int maxn=-1;
__int64 P[505];
int W[505];
__int64 dp[10005];
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int E,F;
cin>>E>>F;
int n;
cin>>n;
for(int i=0;i<n;++i){
cin>>P[i]>>W[i];
}
int pw=F-E;
if(pw==0){cout<<"The minimum amount of money in the piggy-bank is "<<0<<'.'<<endl;continue;}
for(int i=0;i<=pw;++i){
dp[i]=maxn;
}
dp[W[0]]=P[0];
for(int i=W[0]+W[0];i<=pw;){
dp[i]=dp[i-W[0]]+P[0];
i+=W[0];
}
for(int i=1;i<n;++i){
for(int j=W[i];j<=pw;++j){
if(j==W[i]&&dp[j]==maxn){
dp[j]=P[i];
}
else if(j==W[i]){
dp[j]=min(dp[j],P[i]);
}
if(dp[j-W[i]]==maxn)continue;
if(dp[j]!=-1)
dp[j]=min(dp[j],dp[j-W[i]]+P[i]);
else dp[j]=dp[j-W[i]]+P[i];
}
}
if(dp[pw]==maxn)cout<<"This is impossible."<<endl;
else cout<<"The minimum amount of money in the piggy-bank is "<<dp[pw]<<"."<<endl;
}
return 0;
}
HDU 1248——寒冰王座
一道超级简单的题目,代码如下:
#include<iostream>
using namespace std;
int dp[10005];
int value[3]={150,200,350};
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int n;
cin>>n;
for(int i=0;i<=n;++i){
dp[i]=0;
}
for(int i=0;i<3;++i){
for(int j=0;j<=n;++j){
if(j<value[i])continue;
dp[j]=max(dp[j],dp[j-value[i]]+value[i]);
}
}
cout<<n-dp[n]<<endl;
}
return 0;
}