dp专题训练
dp题目
状态转移方程:dp[i]=min(dp[i-1]+a[i],dp[i-2]+b[i-1]);
第i个人,可以自己单独买,也可以和前面一个人一起买;
dp[i]表示到底i个人买票所需要的最小时间。
#include<iostream>
#define maxn 10010
int min(int a,int b){return a<b?a:b;}
int a[maxn]; //单独买票
int b[maxn]; //共同买票
int dp[maxn];
using namespace std;
int main(){
int n,k;
cin>>n;
while(n--){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(dp,0,sizeof(dp));
cin>>k; //有k个人
for(int i=1;i<=k;i++) cin>>a[i];
for(int i=1;i<=k-1;i++) cin>>b[i];
dp[1]=a[1];
//第i个可以单独买票或者 和前面一个人一起买票
for(int i=2;i<=k;i++){
dp[i]=min(dp[i-1]+a[i],dp[i-2]+b[i-1]);
}
int h,m,s;
h=dp[k]/3600;
m=(dp[k]-3600*h)/60;
s=(dp[k]-h*3600-m*60);
h+=8;
if(h>12){
cout<<h<<":";
if(m>=10) cout<<m<<":";
else cout<<"0"<<m<<":";
if(s>=10) cout<<s;
else cout<<"0"<<s;
cout<<" pm"<<endl;
}
else{
if(h>=10) cout<<h<<":";
else cout<<"0"<<h<<":";
if(m>=10) cout<<m<<":";
else cout<<"0"<<m<<":";
if(s>=10) cout<<s;
else cout<<"0"<<s;
cout<<" am"<<endl;
}
}
return 0;
}
01背包问题,花了好久调错,if(f[j]>f[j-w[i]]*v[i]){ f[j]=f[j-w[i]]*v[i]; }
我开始的时候写成了min(f[j],(f[j-w[I]]*v[I]),但是我的min习惯的写成了min(int a,int b)….这里是double类型。。。
#include<iostream>
#define maxn 10010
using namespace std;
int min(int a,int b){return a<b?a:b;}
int main(){
int m,n,w[maxn]; //背包大小n,物品数量m
double v[maxn],f[maxn];
while(cin>>n>>m && (m!=0||n!=0)){
for(int i=1;i<=m;i++){
cin>>w[i]>>v[i];
v[i]=1-v[i]; //反过来算一个都收不到的概率
}
for(int i=0;i<=n;i++)
f[i]=1;
//f[i]表示容量为i的时候的最大价值,这里表示最小概率
//f[j]=min(f[j],f[j-w[i]]+v[i]);
for(int i=1;i<=m;i++){
for(int j=n;j>=w[i];j--){
if(f[j]>f[j-w[i]]*v[i]){
f[j]=f[j-w[i]]*v[i];
}
}
}
printf("%.1lf%%\n",100*(1-f[n]));
}
return 0;
}
完全背包:
#include<iostream>
#define maxn 10010
using namespace std;
int min(int a,int b){return a<b?a:b;}
int dp[maxn];
int main(){
int T,E,F,N;
int w[maxn],v[maxn];
cin>>T;
while(T--){
cin>>E>>F; //E表示空瓶的重量,F表示满瓶的重量
int sum=F-E; //sum为背包的容量
cin>>N; //钱的种类
for(int i=1;i<=N;i++) cin>>v[i]>>w[i];
for(int i=1;i<=sum;i++) dp[i]=10000010; //求最小,dp数组存大数
dp[0]=0; //注意这里的dp[0]初始化
for(int i=1;i<=N;i++){
for(int j=w[i];j<=sum;j++){
dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
}
}
if(dp[sum]==10000010) cout<<"This is impossible."<<endl;
else cout<<"The minimum amount of money in the piggy-bank is "<<dp[sum]<<"."<<endl;
}
return 0;
}