dp:01背包问题

参考:

(40条消息) 总结——01背包问题 (动态规划算法)_青龙指引你的博客-CSDN博客_01背包算法

某工厂预计明年有A、B、C、D四个新建项目,每个项目的投资额Wk及其投资后的收益Vk如下表所示,投资总额为30万元,如何选择项目才能使总收益最大?

W:15 10 12 8

V:12 8 9 5

思路:01背包也算是比较暴力的方法,把所有的可能性罗列,打表,找到每一步的最优解,并进行存储。

 

状态转移方程:

if(j>=w[i])
m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
else
m[i][j]=m[i-1][j];

源代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int v[N]={0,12,8,9,5};
int w[N]={0,15,10,12,8};
int n=4;
int c=30;
int x[N],m[N][N];
void back()//检查拿了哪个元素,并进行标记,实际上是从后往前推的过程
{
    int i;
    for(i=n;i>1;i--)//i>1而不是i>=1
    {
        if(m[i][c]==m[i-1][c])//判断是否拿了的条件,m[i][c]==m[i-1][c]
        x[i]=0;
        else
        {
            x[i]=1;
            c=c-w[i];
        }
    }
    x[1]=(m[i][c]>0)?1:0;
}
void dp()
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=c;j++)
        {
            //核心代码:
            if(j>=w[i])
            {
                m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
             } 
             else
             {
                 m[i][j]=m[i-1][j];
             }
        }
    }
}
int main()
{
    memset(m,0,sizeof(m));
    dp();
    cout<<m[n][c]<<endl;
    back();
    for(int i=1;i<=n;i++)
    cout<<x[i]<<" ";
    return 0;
}

 

posted @ 2022-04-06 22:33  格蕾  阅读(71)  评论(0)    收藏  举报