背包问题,递归解法

#include<iostream.h>
#include
<string.h>

int f[6][501][101];

int v[6= {0,30,50,10,23,130};
int w[6= {0,3,8,2,5,20};
int c[6= {0,10,10,10,8,5};
int t[6= {0,4,5,2,3,11};

const int maxv = 400;
const int maxw = 10;
const int maxn = 5;

int solve(int n , int x, int y)
{
    
if(f[n][x][y] >=0)
        
return f[n][x][y];
    
if( n ==0 || x ==0 || y == 0)
        f[n][x][y] 
= 0;
    
else
    
{

        
int maxi = c[n];
        
if(x / v[n]  < maxi)
            maxi 
= x / v[n];
        
if(y / w[n] < maxi )
            maxi 
= y / w[n];

        
for(int i =0 ; i <= maxi ; ++i)
        
{
            
if ((solve(n-1,x- i * v[n],y - i * w[n]) + i * t[n] ) > f[n][x][y] )
                f[n][x][y] 
= solve(n-1,x- i * v[n],y - i * w[n]) + i * t[n];
        }

    }

    
return f[n][x][y] ;
}


void main()
{
    memset(f,
0xff,sizeof(f));

    
int ans = 0;

    
for(int x = 1 ; x <= maxv ; ++x)
        
for(int y = 1 ; y <= maxw ; ++y)
        
{
            
if( solve(5,x,y)  > ans )
                ans 
= solve(5,x,y);
        }


    cout
<<ans;
}
 
### 0-1 背包问题递归解决方案 #### 定义与描述 0-1背包问题是组合优化中的经典难题之一。给定一组物品,每种物品具有一定的重量和价值,在限定总重量的情况下如何选择这些物品使得所选物品的价值之和最大。 #### 递归算法解释 对于每一个物品有两种情况:要么放入中;要么不放。如果当前考虑的是第`i`件物品,则可以表示成如下两种状态转移方程: - 如果该物品被选取,则剩余容量减少其对应的体积,并上此物的价值; - 若未选取则保持原有最佳解不变。 这种思路可以通过递归来实现,即通过不断缩小子问题规模直到遇到最小子问题为止[^1]。 #### Python 实现代码 下面是一个简单的Python函数来展示这一过程: ```python def knapSack(W, wt, val, n): # Base Case if n == 0 or W == 0 : return 0 # If weight of the nth item is more than Knapsack capacity W, # then this item cannot be included in the optimal solution if (wt[n-1] > W): return knapSack(W, wt, val, n-1) # Return the maximum value between two cases: # (1) nth item not included # (2) nth item included else: return max(val[n-1] + knapSack(W-wt[n-1], wt, val, n-1), knapSack(W, wt, val, n-1)) # Test case data from reference material [^2] val = [60, 100, 120] wt = [10, 20, 30] W = 50 n = len(val) print(knapSack(W, wt, val, n)) ``` 上述程序定义了一个名为 `knapSack()` 的函数用于计算最优解的最大值。这里采用了自顶向下的方法构建了解决方案树并最终返回最高可能获得的价值。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值