hdu 2639 Bone Collector II (0/1背包)

简介: 点击打开链接hdu 2639 思路: 0/1背包求第k优解 分析: 1 其基本思想是,将每个状态都表示成有序队列,将状态转移方程中的 max/min 转 化成有序队列的合并。

点击打开链接hdu 2639

思路: 0/1背包求第k优解
分析:
1 其基本思想是,将每个状态都表示成有序队列,将状态转移方程中的 max/min 转 化成有序队列的合并。
2 这里仍然以 01 背包为例讲解一下。
   首先看 01 背包求最优解的状态转移方程: F [i, v] = max{F [i − 1, v], F [i − 1, v −Ci ] + Wi }。如果要求第 K 优解,那么状态 F [i, v] 就应该是一个大小为 K 的队列F [i, v, 1 . . . K]。其中 F [i, v, k] 表示前 i 个物品中,背包大小为 v 时,第 k 优解的值。这里也可以简单地理解为在原来的方程中加了一维来表示结果的优先次序。显然f [i, v, 1 . . . K] 这 K 个数是由大到小排列的,所以它可看作是一个有序队列。然后原方程就可以解释为: F [i, v] 这个有序队列是由 F [i − 1, v] 和 F [i − 1,v −Ci ] + Wi 这两个有序队列合并得到的。前者 F [i − 1][V ] 即 F [i − 1, v, 1 . . . K],后者F [i − 1,v − Ci ] + Wi 则理解为在 F[i − 1,v − Ci , 1 . . . K] 的每个数上加上 Wi 后得到的有序队列。合并这两个有序队列并将结果的前 K 项储存到 f [i, v, 1 . . . K] 中的复杂度是O(K)。最后的第 K 优解的答案是 F [N, V, K]。总的时间复杂度是 O(V N K)。
3 这边的难点就是在于合并,但是只要懂得了归并排序的这边都不难理解,还有要注意的一个地方就是题目说了把相同的值看成是一样的,所以这边的1~k的值是严格的递减,在合并的时候注意

代码:

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

const int MAX = 110;
const int MAXN = 1010;

int n , sumv , k;
int v[MAX] , w[MAX] , dp[MAXN][MAX];

int solve(){
    int arrOne[MAX] , arrTwo[MAX];
    memset(dp , 0 , sizeof(dp));
    for(int i = 1 ; i <= n ; i++){
        for(int j = sumv ; j >= v[i] ; j--){
            for(int cnt = 1 ; cnt <= k ; cnt++){
                arrOne[cnt] = dp[j][cnt]; 
                arrTwo[cnt] = dp[j-v[i]][cnt]+w[i]; 
            }
            int a , b , c;
            a = b = c = 1;
            // 归并排序
            while(c <= k && a <= k && b <= k){
                 if(arrOne[a] > arrTwo[b]) 
                     dp[j][c] = arrOne[a++];
                 else
                     dp[j][c] = arrTwo[b++];
                 // 注意值相同的算一个
                 if(dp[j][c] != dp[j][c-1])
                     c++;
            }
            while(a <= k && c <= k){
                dp[j][c] = arrOne[a++];
                // 注意值相同的算一个
                if(dp[j][c-1] != dp[j][c])
                    c++;
            }
            while(b <= k && c <= k){
                dp[j][c++] = arrTwo[b++];
                // 注意值相同的算一个
                if(dp[j][c-1] != dp[j][c])
                    c++;
            }
        }
    }
    return dp[sumv][k];
}

int main(){
    int Case;
    scanf("%d" , &Case);
    while(Case--){
         scanf("%d%d%d" , &n , &sumv , &k); 
         for(int i = 1 ; i <= n ; i++)
             scanf("%d" , &w[i]);
         for(int i = 1 ; i <= n ; i++)
             scanf("%d" , &v[i]);
         printf("%d\n" , solve()); 
    }
    return 0;
}



目录
相关文章
|
监控 前端开发 Java
开发者学堂课程干货总结——Spring Boot 2.5.x开发实战(八)
Spring Boot 2.5.x开发实战课时8——Spring Boot 2.5实战API帮助文档Swagger,Spring Boot 2.5.x开发实战是学习Java Spring Cloud微服务架构的必经之路。电子书+视频为同学带来最佳学习效果,文字、课程链接、图谱地址统统为大家放送了哦
开发者学堂课程干货总结——Spring Boot 2.5.x开发实战(八)
|
新零售 安全 固态存储
CDN新品发布:阿里云SCDN安全加速开放公测
SCDN(Secure+CDN)安全加速产品是CDN推出的一款集合安全能力的内容加速服务,用户就近取得所需内容解决因分布、带宽、服务器性能带来的访问延迟问题,提升网站访问速度。同时防护DDoS,CC,Web应用攻击,恶意刷流量,恶意爬虫等危害网站的行为。
7196 0
希望OFFICE有一个小阳台,在阳光斜照的下午,开发人员能喝着茶,在蓝色的天空下讨论问题,这样思绪更为清楚
希望OFFICE有一个小阳台,在阳光斜照的下午,开发人员能喝着茶,在蓝色的天空下讨论问题,这样思绪更为清楚
|
22小时前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
10天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
4天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
430 191
|
3天前
|
数据采集 消息中间件 人工智能
跨系统数据搬运的全方位解析,包括定义、痛点、技术、方法及智能体解决方案
跨系统数据搬运打通企业数据孤岛,实现CRM、ERP等系统高效互通。伴随数字化转型,全球市场规模超150亿美元,中国年增速达30%。本文详解其定义、痛点、技术原理、主流方法及智能体新范式,结合实在Agent等案例,揭示从数据割裂到智能流通的实践路径,助力企业降本增效,释放数据价值。