几道题都是0-1背包问题,放在一起
HDU 2602Bone Collector
第一种没有优化空间的代码:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1005;
int value[maxn];
int vol[maxn];
int dp[maxn][maxn];
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int n,v;
cin>>n>>v;
for(int i=0;i<n;++i){
cin>>value[i];
}
for(int i=0;i<n;++i){
cin>>vol[i];
}
memset(dp,0,sizeof(dp));
for(int j=0;j<=v;++j){
if(j>=vol[0])
dp[0][j]=value[0];
}
for(int i=1;i<n;++i){
for(int j=0;j<=v;++j){
dp[i][j]=dp[i-1][j];
if(j-vol[i]<0)continue;
dp[i][j]=max(dp[i][j],dp[i-1][j-vol[i]]+value[i]);
// cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
}
}
int ans=0;
for(int i=0;i<=v;++i){
if(dp[n-1][i]>ans)ans=dp[n-1][i];
}
cout<<ans<<endl;
}
return 0;
}
优化空间以后
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1005;
int value[maxn];
int vol[maxn];
int dp[maxn];
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int n,v;
cin>>n>>v;
for(int i=0;i<n;++i){
cin>>value[i];
}
for(int i=0;i<n;++i){
cin>>vol[i];
}
memset(dp,0,sizeof(dp));
for(int j=0;j<=v;++j){
if(j>=vol[0])
dp[j]=value[0];
}
for(int i=1;i<n;++i){
for(int j=v;j>=0;--j){
if(j<vol[i])break;
dp[j]=max(dp[j],dp[j-vol[i]]+value[i]);
}
}
cout<<dp[v]<<endl;
}
return 0;
}
HDU 1203——I NEED A OFFER!
结合了一下概率,代码如下:
#include<iostream>
#include<iomanip>
using namespace std;
const int maxn=10000+5;
int cost[maxn];
double posi[maxn];
double dp[maxn];
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int m,n;
while(cin>>n>>m){
if(m==0&&n==0)break;
for(int i=0;i<m;++i){
cin>>cost[i]>>posi[i];
}
for(int i=0;i<=n;++i){
dp[i]=0;
}
for(int i=0;i<m;++i){
for(int j=n;j>=0;--j){
if(j-cost[i]<0)break;
dp[j]=max(dp[j],1-(1-dp[j-cost[i]])*(1-posi[i]));
}
}
cout<<setiosflags(ios::fixed)<<setprecision(1)<<dp[n]*100<<'%'<<endl;
}
return 0;
}
这两题都有过忘记把读文件的那句注释掉的时候,发现有时候没有注释掉错误类型会显示re,而有时候会显示WA。
HDU 2955——Robberies
首先记录下可能达到的数值(即所有银行里钱的总量),然后dp的最大值就是这个数值。dp[i]表示抢到i块钱被逮捕的最大概率。代码如下:
#include<iostream>
using namespace std;
const int maxn=100+5;
int Mj[maxn];
double Pj[maxn];
double dp[10005];
int main(){
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int n;
double p;
cin>>p>>n;
int tot=0;
for(int i=0;i<n;++i){
cin>>Mj[i]>>Pj[i];
tot+=Mj[i];
}
for(int i=0;i<=tot;++i){
dp[i]=-1;
}
for(int j=0;j<=tot;++j){
if(j<=Mj[0])
dp[j]=1-Pj[0];
}
for(int i=1;i<n;++i){
for(int j=tot;j>=0;--j){
if(j==Mj[i]){
dp[j]=max(dp[j],1-Pj[i]);
}
if(j<Mj[i])break;
if(dp[j-Mj[i]]==-1)continue;
dp[j]=max(dp[j],(dp[j-Mj[i]])*(1-Pj[i]));
}
}
int ans=0;
for(int i=0;i<=tot;++i){
if((1-dp[i])<p&&(dp[i]!=-1))ans=i;
}
cout<<ans<<endl;
}
return 0;
}