动态规划0/1背包问题和数字三角形

 


 

 

#include<iostream>

#include<algorithm>

#define MAX 101

using namespace std;

int D[MAX][MAX];

int minSum[MAX][MAX];

int n;

int MinSum(int i, int j)

{

   if (minSum[i][j] != -1)

       return minSum[i][j];

   if (i == n)

       return D[i][j];

   int x = MinSum(i + 1, j);

   int y = MinSum(i + 1, j + 1);

   return min(x, y) + D[i][j];

}

int main()

{

   int i, j;

   cout<<"请输入三角形的行数"<<endl;

   cin >> n;

   for (i = 1; i <= n; i++)

       for (j = 1; j <= i; j++)

              {

           cin >> D[i][j];

           minSum[i][j] = -1;

       }

   cout <<"最短路径长为:"<<MinSum(1, 1) << endl;

       system("pause");

}

 

#include<iostream>

#include<stack>

#include<vector>

using namespace std;

stack<int> KnapSack(intc,vector<int> w,vector<int> v,int &max_m)

{

   vector<vector <int> > m(w.size(),vector<int>(c+1));

   stack<int> res;

   int i,j;

   max_m=0;

   for(j=0;j<c+1;j++) //对于m[n][j]

       if(j<w[w.size()-1])

           m[w.size()-1][j]=0;  //j<w[n]时,物品n不能放入背包中,此时背包的价值为。

       else

           m[w.size()-1][j]=v[v.size()-1]; //j>=w[n]时,物品n可以放入背包,此时背包的价值为v[n]

   for(i=w.size()-2;i>=0;i--) //对于m[i][j]

    {

       for(j=0;j<c+1;j++)

           if(j<w[i])          //j<w[i]时,物品i不能放入背包中,此时背包的价值为m[i+1][j]

                m[i][j]=m[i+1][j];

           else                //j>=w[i]时,物品n可以放入背包

           {

                int m1=m[i+1][j];  //当物品i不放入背包时,能达到的最大价值为m[i+1][j]

                intm2=m[i+1][j-w[i]]+v[i];  //当物品i放入背包后,对于物品i+1n,能达到的最大价值为m[i+1][j-w[i]]+v[i]

                m[i][j]=m1>m2?m1:m2;         //两者取其大者      

           }   

    }

/*   cout << "最优值矩阵:"<<endl;

   for(i=0;i<w.size();i++)

    {

       for(j=0;j<c+1;j++)

           cout<<m[i][j]<<" ";

       cout <<endl;

   }   

   cout <<endl;

   */

   j=c;

   for(i=0;i<w.size()-1;i++)

    {

       if(m[i][j]!=m[i+1][j])

       {

           res.push(i+1);

           max_m+=v[i];

           j=j-w[i];       

       }

   }   

   if(m[w.size()-1][j]!=0)

    {

       res.push(w.size());

       max_m+=v[w.size()-1];

   }   

       

   return res;   

}

int main()

{

   vector<int> weight;

   vector<int> value;

   stack<int>  result;

   int max_weight;

   int tmp;

   int result_m=0;

   cout<< "输入背包最大容量"<<endl;

   cin >> max_weight;

   cout <<"输入物品重量,以结束"<<endl;

   while(1)

    {

       cin>>tmp;

       if(tmp!=0)

           weight.push_back(tmp);

       else

           break;

   }   

   cout <<"物品重量: "<<endl;

    for(inti=0;i<weight.size();i++)

       cout <<weight[i]<<" ";

   cout << endl;

   cout <<"输入物品权重,以结束"<<endl;

   while(1)

    {

       cin>>tmp;

       if(tmp!=0)

           value.push_back(tmp);

       else

           break;

    }

   cout <<"物品权重: "<<endl;

   for(int i=0;i<value.size();i++)

       cout <<value[i]<<" ";

   cout << endl;

   result=KnapSack(max_weight,weight,value,result_m);

   cout <<"放入背包的物品为:"<<endl;

   while(!result.empty())

    {

       cout <<result.top()<<" ";

       result.pop();

    }

   cout <<endl;

   cout<<"背包最大价值为:"<<result_m<<endl;

   return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值