动态规划:叠放箱子

来源:互联网 发布:淘宝五心需要多少好评 编辑:程序博客网 时间:2024/05/13 17:26

动态规划:叠放箱子
问题描述:
某港口有一批箱子,将其编号,分别为1至N。每个箱子的尺寸规格都是一样的,现在要将其中的某些箱子叠放起来,箱子叠放规则是:
1:每个箱子上最多只能直接叠放一个箱子;
2:编号较小的箱子不能直接放在编号较大的箱子之上;
3:每个箱子都给出了自身重量与可承受重量,每个箱子之上的所有箱子重量之和不得超过该箱的可承受重量.
要求:编程选择最多的满足条件的箱子。
分析:
当我看到条件的时候,自动与0-1背包问题对应:最多只能放一个就是选择放与不放的问题。

我们定义目标函数f[i][j]表示第i个箱子到第N个箱子中总重量为j的最大箱子数.
方程:
f[i[j]=max(f[i+1][j],f[i+1][j-weight[i]]+1);
能选的条件是:j>=weight[i]&&capacity[i]>=j-weight[i];

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=400;int weight[maxn];int dp[maxn][maxn];int capacity[maxn];bool mark[maxn];int p[maxn];int n,number;bool visit[maxn];void dfs(int cnt,int ans,int flag){//找出最优解    if(cnt==number){        if(ans==0){            for(int k=0;k<number;k++)            cout<<p[k]<<" ";        }        return ;        }    for(int i=flag;i<=n;i++){    if(visit[i]==false&&ans-weight[i]>=0){        visit[i]=true;        p[cnt]=i;    dfs(cnt+1,ans-weight[i],i);        visit[i]=false;    }}}int main(){   int i,j;   cin>>n;   for(i=1;i<=n;i++){       cin>>weight[i];   }   for(i=1;i<=n;i++){    cin>>capacity[i];}int sum=0;memset(dp,0,sizeof(dp));memset(mark,false,sizeof(mark));memset(visit,false,sizeof(visit));for(i=n;i>=1;i--){    sum=0;    for(j=i;j<=n;j++)    sum+=weight[j];    for(int k=0;k<=sum;k++){        dp[i][k]=dp[i+1][k];//不选第i个箱子        if(k-weight[i]>=0&&capacity[i]>=k-weight[i]){//选择第i个箱子的条件k-weight[i]表示去除自身重量后            dp[i][k]=max(dp[i][k],dp[i+1][k-weight[i]]+1);}}}number=0;for(i=1;i<=sum;i++)number=max(dp[1][i],number);for(i=1;i<=sum;i++)if(dp[1][i]==number)    dfs(0,i,1);return 0;}
阅读全文
0 0
原创粉丝点击