[JZOJ P1281] [DP]背包的第k优解

本文针对一种特殊的三维背包问题进行探讨,作者通过分析题目的特点,采用三维数组进行状态表示,并结合具体的C++代码实现了解决方案。文章记录了从理解题目到逐步优化代码的过程。

@kaike

传送门

看了半天,不会写

没见过这种题型,看了背包九讲,然而只有很简单的几句话

我认为就是多加了一维,变成三维数组

由于必须恰好等于包的容量,所以要赋最小值

然而不能那样递推为什么我也不知道

还没悟出来

嗯加油

 

 1 #include<iostream>  
 2 using namespace std;  
 3 long f[51][50001];  
 4 int q1[51];  
 5 int q2[51];  
 6 int main()  
 7 {   
 8     int k,v,n;  
 9     int value,weight;  
10     cin>>k>>v>>n;  
11     for(int i=0;i<=k;i++)  
12         for(int j=0;j<=v;j++)  
13             f[i][j]=-99999999;//赋初值
14     f[1][0]=0;//当背包容量为0时,赋值0
15     for(int i=1;i<=n;i++)//枚举背包  
16     {  
17         cin>>weight>>value;  
18         for(int j=v;j>=weight;j--)//枚举容量
19         {  
20             for(int w=1;w<=k;w++)//枚举k包 从1-k
21             {  
22             q1[w]=f[w][j];  
23             q2[w]=f[w][j-weight]+value;  
24             }
25             int h1=1,h2=1,h=0;  
26             while(h<k)
27             {  
28                 h++;  
29                 if(q1[h1]>q2[h2]) {  
30                     f[h][j]=q1[h1];  
31                     h1++;  
32                 }  
33                 else {  
34                     f[h][j]=q2[h2];  
35                     h2++;  
36                 }  
37             }  
38         }  
39     }
40         int ans=0;  
41         for(int i=1;i<=k;i++)  
42             ans+=f[i][v];  
43         cout<<ans<<endl;  
44         return 0;  
45 }  
你蠢

 

转载于:https://www.cnblogs.com/Kaike/p/5950533.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值