yoj 01背包(输出选择的序号)

本文介绍了一种解决0-1背包问题的方法,通过动态规划算法实现最优解的计算,详细展示了输入输出样例及代码实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2335: 0-1背包问题

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 98  Solved: 61
[Submit][Status][Web Board]

Description

 试设计一个用回溯法搜索子集空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解0-1背包问题。 0-1 背包问题描述如下:给定n 种物品和一个背包。物品i 的重量是wi ,其价值为vi ,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有2 种选择,即装入背包或不装入背包。不能将物品i 装入背包多次,也不能只装入部分的物品i。

Input

第一行有2个正整数n和c。n是物品数,c是背包的容量。接下来的1 行中有n个正整数,表示物品的价值。第3 行中有n个正整数,表示物品的重量。 
 

Output

将计算出的装入背包物品的最大价值和最优装入方案输出。第一行输出为:Optimal value is
 

Sample Input

5 10
6 3 5 4 6
2 2 6 5 4

Sample Output

Optimal value is
15
1 1 0 0 1

 

 

#include<cstdio>#include<cstring>#include<cmath>#include<set>#include<cstdlib>#include<iostream>#include<algorithm>using namespace std;

#define MAXN 202

#define INF 999999

int main()

    int dp[105][105],v[105],w[105],vis[105];

    int n,V;

    scanf("%d%d",&n,&V);

    for(int i=0; i<n; i++) 

      scanf("%d",&v[i]); 

  for(int i=0; i<n; i++) 

      scanf("%d",&w[i]);

    memset(dp,0,sizeof(dp)); 

  for(int i=0; i<n; i++) 

      for(int j=0; j<=V; j++)   

    {         

         if(j<w[i])         

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

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

      }   

int k=V;//    for(int i=0;i<=n;i++)//    {//        for(int j=0;j<=V;j++)//            cout<<dp[i][j]<<"  ";//        cout<<endl;//    } 

  for(int i=n;i>0;i--) 

  {     

  if(dp[i][k]>dp[i-1][k])   

    {         

           vis[i-1]=1;//从最后面一个开始判断,是否前i种物品在V质量内所组成价值大于前i-1种,如果是那就是         

         k-=w[i-1];//说明将第i种物品加入到背包当中去        }     

  else       

    vis[i-1]=0; 

  }//    for(int i=0;i<n;i++)//        cout<<vis[i]<<" ";//    cout<<endl;    puts("Optimal value is");    printf("%d\n",dp[n][V]);    int i;    for(i=0; i<n; i++)        printf("%d ",vis[i]);    printf("\n");    return 0;}

 

注意:采用不同的dp循环方式,得到的答案(这里仅指选择的种类)可能不一,但最终的最大值是一样的

如 n=4,     (w,v)={(2,3)   (1,2)   (3,4)   (2,2)}    V=5;

采用上面的就是1010

但是dp如果是这样

for(int i=n-1; i>=0; i--)
        for(int j=0; j<=V; j++)
        {
            if(j<w[i])
                dp[i][j]=dp[i+1][j];
            else
                dp[i][j]=max(dp[i+1][j],dp[i+1][j-w[i]]+v[i]);
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值