ZCMU—1709

news/2024/11/7 18:37:45/

1709: 搬行李

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 15  Solved: 2
[Submit][Status][Web Board]

Description

开学了,又要搬行李,这次你粑粑有2辆车帮你搬,但是不能超载哦。现在给出n(n<=10)件行李的体积,以及2个车子的容量c1,c2(c1<=100,c2<=100),问题就是需要搬运几次?(当然,2辆车是同时过去的,同时回来的,这样算一次)

Input

输入一行T

第二行 n,c1,c2

第三行 n个数

Output

输出需要运输的次数(每组案例输出后面有一行空行)

Sample Input

2

6 12 13

3 9 13 3 10 11

7 1 100

1 2 33 50 50 67 98

Sample Output

zcmu #1: 2

 

zcmu #2: 3

 

【分析】

数据很小 n<=10 ,但是显然上来搜就会gg...那当然按照吉老师的说法应该还是有一些优秀的黄金搜索能搜过去的吧...

如果不考虑搜索,那么这么小的n就是摆明了告诉你状压dp的...(1<<n)压一下选择物品的物品,如果从这里考虑的话就会稍微清晰一点了......那么对于两种状态,只要这两种状态之间没有重复的选择,也就是如果有两个状态x,y ,那么只要x&y == 0 就意味着这两种选择的状态是不冲突的,就可以合并,接下去只要找出最小的合并步数合并成(1<<n)-1就可以求出答案了

仿佛解决了一切问题的思路。。。。

虽然状态合并解决了,但是什么样的状态才能合并呢? 显然这里还有一个问题,不是任意两个状态只要x&y==0就可以合并的,显然我们应该考虑的是从当前状态x出发,经过一趟运输状态y,合并出目标状态x|y,同时步数+1,所以我们还需要解决运输状态,运输状态很好理解,只要一趟运输可以装的下,那就是一个可行的运输状态

这样考虑的话就比较明朗了,对所有的状态我们只要考虑每个运输状态往前装就行了....就变成类似背包的思路了...

所以首先解决运输状态的pending,对一个状态,怎么判断这是一个可行的运输状态,显然就是这次状态中被选择的物品可以装上两辆车,那么我们对一辆车进行背包,剩下的物品全塞进另一辆车就行了...

这里假装自己加了个优化,用体积小的车做背包......当然并没有什么必要...数据范围太小了

然后对所有可行的运输状态做一次背包...直接塞就行了...gg

太久没做题了....状压dp真的写不来了...太菜了

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
int f[10000];
int a[10000];
int v[10000];
int bag[10000];
int len,n,c1,c2;bool check(int x){len = 0;int all = 0;for (int i = 0 ; i < n ; ++i)if (x & (1<<i)){v[len++] = a[i];all += a[i];}memset(bag,0,sizeof(bag[0]) * (c1 + 10));for (int i = 0 ; i < len ; ++i)for (int j = c1 ; j >= v[i] ; --j)bag[j] = max(bag[j],bag[j - v[i]] + v[i]);all -= bag[c1];if (all <= c2) return true;return false;
}int main()
{int pp;scanf("%d",&pp);for (int cas = 1 ; cas <= pp; ++cas){scanf("%d%d%d",&n,&c1,&c2);if (c1 > c2) swap(c1,c2);for (int i = 0 ; i < n ; ++i) scanf("%d",&a[i]);memset(f,0x3f3f3f3f,sizeof(f[0]) * ( (1<<n) + 100) );vector<int> can;	for (int i = 0 ; i < (1<<n) ; ++i){if (check(i)){f[i] = 1;can.push_back(i);}}len = can.size();for (int i = 0 ; i < len ; ++i){for (int j = (1<<n) - 1 ; j >= 0 ; --j){if ( (can[i] & j) == 0){int go = can[i] | j;f[go] = min(f[j] + 1,f[go]);}}}printf("zcmu #%d:\n%d\n\n",cas,f[(1<<n) - 1]);}return 0;
}

 


http://www.ppmy.cn/news/147258.html

相关文章

uC/OS-III-3.0-uC/OS-III简介

1.OS-III是一个第 3代的系统内核&#xff0c;支持现代的实时内核所期待的大部分功能。 例如资源管理&#xff0c; 同步&#xff0c; 任务间的通信等等。然而&#xff0c; uC/OS-III提供的特色功能在其它的实时内核中是找不到的&#xff0c; 比如说完备的运行时间测量性能&#…

zcmu1007

Description 一场考试结束后&#xff0c;经常要统计一个班级的平均分。 请写一个程序&#xff0c;计算每个班级的平均分。 Input 输入每一行第一个整数n&#xff0c;表示待求平均分的班级人数有n个人&#xff0c;接着是n个人的分数。 当n0时&#xff0c;输入结束&#xff0c;不…

U821升级到U810.1注意事项

1、找到客户在2011年1月份的导出记录.BA_和.lst文件&#xff0c;导出索引文件为UFErpYer.lst 2、修改UFErpYer.lst为UFErpAct.lst&#xff0c;修改文件内容&#xff1a; TypeYear 改为 TypeAccount 增加年度信息&#xff0c;如&#xff1a; YCount10 YYear02,03,04,05,06,07,0…

UC/OS和uClinux的比较 + μC/OS-II与eCos的比较

UC/OS和uClinux的比较 引言 随着现代计算机技术的飞速发展和互联网技术的广泛应用&#xff0c;从PC时代过渡到了以个人数字助理、手持个人电脑和信息家电为代表的3C&#xff08;计算机、通信、消费电子&#xff09;一体的后PC时代。后PC时代里&#xff0c;嵌入式系统扮演了越…

[uC/OS-III] 21. 信号量

1. 信号量基本概念 信号量&#xff08;Semaphore&#xff09;是一种实现任务间通信的机制&#xff0c;可以实现任务之间同步或临界资源的互斥访问&#xff0c; 常用于协助一组相互竞争的任务来访问临界资源。二值信号量&#xff1a;在 uCOS 中我们用信号量用于同步&#xff0c…

uC/OS-II 中文手册

uC/OS-II 中文手册 - 1 - 315 - 1 - 第一章 范例 在这一章里将提供三个范例来说明如何使用 μC/OS-II。笔者之所以在本书一开始就写 这一章是为了让读者尽快开始使用 μC/OS-II。在开始讲述这些例子之前&#xff0c;笔者想先说明一 些在这本书里的约定。 这些例子曾经用B…

uC/OS-II与uC/OS-III的区别

实时操作系统分为硬实时和软实时两类&#xff0c;两者的区别在于对于处理线程超时以及超时带来的后果的容忍度。 1、定位 uC/OS-II定位于8/16位以及底端32位的CPU uC/OS-III定位高端32以及高端16位的CPU 2、任务调度算法 uC/OS-II:优先级软件查表算法 uC/OS-III:有CLZ指令&…

ZCMU 1074-1079

1074: 求1&#xff0b;1/2&#xff0b;1/3&#xff0b;...&#xff0b;1/n Description 输入一个正整数 repeat (0<repeat<10)&#xff0c;做repeat 次下列运算&#xff1a; 读入 1 个正整数 n(n<50)&#xff0c;计算并输出1&#xff0b;1/2&#xff0b;1/3&#xff0…