在实际应用中,展示动态规划的用法。
01背包问题
#include<iostream>
#include<cstring>
using namespace std;
int val[5000];
int wei[5000];
int f[13000];
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
memset(f,0,sizeof(f));
int n,m;
cin>>n>>m;
for(int i=0;i<n;++i)
cin>>wei[i]>>val[i];
for(int i=0;i<n;++i)
for(int j=m;j>=wei[i];j--)
{
f[j]=max(f[j-wei[i]]+val[i],f[j] ); //逗号前方表示包中选中此物品,后方表示上次状态容积为 j 时,对背包的使用
}
cout<<f[m]<<endl;
}
之所以要使 j 从容量循环到第 i 个包的质量,是因为只有在这个范围内才可能装下第 i 个物品。
举例2:点击打开链接
大意:一共有n个管道,每个管道的价格和流量不同,一个设备由不同的管道构成,每种管道有多种选择,他们的价格或流量不同,结果应选出价格之和最小与最小管道流量最大的组合。
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<iomanip>
using namespace std;
#define max(a,b) (a>b?a:b)
struct reco
{
int b;
int p;
}re[120][120];
int mip[120];
int dp[120][1200];//dp[i][j],,,i表示第i号线路,j表示流量
int main()
{
int T;
cin>>T;
while(T--)
{
memset(dp,9999999,sizeof(dp));
memset(re,0,sizeof(re));
memset(mip,0,sizeof(mip));
int line;
cin>>line;
int b,p,maxb=-99;
for(int i=1;i<=line;++i)
{
cin>>mip[i];
for(int q=1;q<= mip[i];++q)
{
cin>>b>>p;
if(b>maxb)
maxb=b;
re[i][q].b=b;
re[i][q].p=p;
}
}
for(int i=0;i<=maxb;++i) //后面会用到dp[0][],而其值应为0.
dp[0][i]=0;
float ans=0;
for(int i=1;i<=line;++i)
for(int j=1;j<=mip[i];++j)
{
for(int k=1;k<=re[i][j].b;++k)
dp[i][k]=min(dp[i][k],dp[i-1][k]+re[i][j].p); //前面有提示 k<=re[i][j],说明上次流量小于当前流量,进行更新
}
for(int i=1;i<=maxb;++i)
ans=max(ans,1.0*i/dp[line][i]);
cout<<fixed<<setprecision(3)<<ans<<endl;
}
}
完全背包问题:
每种物品都可以取任意次。
#include<iostream>
#include<cstring>
using namespace std;
int min(int a,int b)
{
return a>b?b:a;
}
int dp[10010];
int weic;//重量
int valc;//面值
int weight;
void solve()
{
int n;
cin>>n;
for(int i=0;i<n;++i)
{
cin>>valc>>weic;
if(dp[weic]==-1)
dp[weic]=valc;
else
dp[weic]=min(dp[weic],valc);
for(int j=0;j+weic<=weight;++j)
{
if(dp[j]==-1)
continue;
else if(dp[j+weic]==-1)
dp[j+weic]=dp[j]+valc;
else
{
dp[j+weic]=min(dp[j+weic],dp[j]+valc);
}
}
}
if(dp[weight]!=-1)
cout<<"The minimum amount of money in the piggy-bank is "<<dp[weight]<<"."<<endl;
else
cout<<"This is impossible."<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int b,a;
cin>>b>>a;
weight=a-b;
memset(dp,-1,sizeof(dp));
solve();
}
}
未完待续。。。