uva10857(状态压缩DP)
uva10857
题意
兔子希望在平面上 n 个点上放蛋,每个点最多放一个蛋,初始兔子在 (0, 0) 点,这里有无数个蛋,兔子可以回到这个点取蛋,兔子的速度为 \(v * 2^{-i}\)(i 为携带蛋的数量)。对于每个点 (x, y) ,在 \(720+x/2000\) 分钟后不能在该点放蛋了。问最多放几个蛋。
分析
状态压缩DP。
dp[i][j][k] 表示到 i 点时,所有点的状态为 j ,身上携带 k 个蛋的最短时间。
可以使用 BFS 进行记忆化搜索。但是直接这样搜 \(O(2^{17}*18^3)\) 复杂度太高。
发现兔子速度的计算公式,\(v * 2^{-i}\),当 i 很大时,速度会非常小。
考虑一种特殊情况,只有两个点 A(0, a), B(0, a + b) ,如果每次只携带一个蛋,那么分别在 A B 放 2 个蛋所需时间为 \(a * 2 + a + a * 2 + b * 2 = 5a + 2b\) ,一次性携带两个蛋所需时间为 \(4a + 2b\),携带两个蛋更优;
假如有三个点 A(0, a) B(0, a + b) C(0, a + b + c),一次性携带三个蛋所需时间为 \(8a + 4b + 2c\),而选择先带一个蛋放到 A,再带两个蛋,所需时间为 \(2 * a + a + 4 * a + 4 * b + 2 * c = 7a + 4b + 2c\),也就是说分开来带更优,对于更多的点也可以证明。
所以 k 的最大值为 2,也就是说从初始点最多只能带一个或两个蛋出来。
code
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 18;
const double INF = 0x3f3f3f3f;
const double eps = 1e-9;
int n;
double v, dis[MAXN][MAXN];
double dist(double x1, double y1, double x2, double y2) {
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
int x[MAXN], y[MAXN];
double dp[MAXN][1 << MAXN][3];
double maxtime[MAXN];
struct P {
int pos, state, cnt;
};
void bfs() {
queue<P> q;
q.push(P{0, 0, 2});
q.push(P{0, 0, 1});
dp[0][0][0] = 0;
dp[0][0][1] = 0;
dp[0][0][2] = 0;
while(!q.empty()) {
P p = q.front(); q.pop();
for(int i = 1; i <= n; i++) {
if(!((p.state >> i) & 1)) {
P np;
np.state = p.state + (1 << i);
if(p.cnt) {
np.cnt = p.cnt - 1;
np.pos = i;
double ctime = dis[p.pos][i] / v * (1 << p.cnt);
if(dp[p.pos][p.state][p.cnt] + ctime < maxtime[i]) {
if(fabs(dp[np.pos][np.state][np.cnt] - INF) < eps) { // eps
q.push(P{np.pos, np.state, np.cnt});
}
dp[np.pos][np.state][np.cnt] = min(dp[np.pos][np.state][np.cnt], dp[p.pos][p.state][p.cnt] + ctime);
}
} else {
double ctime = dis[p.pos][0] / v; // 从当前点回到 0 点
double ctime1 = dis[0][i] / v * 2, ctime2 = dis[0][i] / v * 4; // 从 0 点拿 1 个或 2 个到当前点的时间
np.pos = i;
np.cnt = 0;
if(dp[p.pos][p.state][p.cnt] + ctime + ctime1 < maxtime[i]) {
if(fabs(dp[np.pos][np.state][np.cnt] - INF) < eps) {
q.push(P{np.pos, np.state, np.cnt});
}
dp[np.pos][np.state][np.cnt] = min(dp[np.pos][np.state][np.cnt], dp[p.pos][p.state][p.cnt] + ctime + ctime1);
}
np.cnt = 1;
if(dp[p.pos][p.state][p.cnt] + ctime + ctime2 < maxtime[i]) {
if(fabs(dp[np.pos][np.state][np.cnt] - INF) < eps) {
q.push(P{np.pos, np.state, np.cnt});
}
dp[np.pos][np.state][np.cnt] = min(dp[np.pos][np.state][np.cnt], dp[p.pos][p.state][p.cnt] + ctime + ctime2);
}
}
}
}
}
}
int bits1[1 << MAXN];
int main() {
while(cin >> n >> v && (n + v)) {
x[0] = 0; y[0] = 0;
for(int i = 0; i <= n; i++) {
for(int j = 0; j < 3; j++) {
for(int k = 0; k < (1 << (1 + n)); k++) {
dp[i][k][j] = INF;
}
}
}
for(int i = 1; i <= n; i++) {
cin >> x[i] >> y[i];
}
for(int i = 0; i <= n; i++) {
maxtime[i] = (720 + (1.0 * x[i] / 2000)) * 60;
for(int j = 0; j <= n; j++) {
dis[i][j] = dist(x[i], y[i], x[j], y[j]);
}
}
bfs();
int ans = 0;
for(int i = 0; i <= n; i++) {
for(int k = 0; k < 3; k++) {
for(int j = 0; j < (1 << (n + 1)); j++) {
bits1[j] = bits1[j >> 1] + (j & 1);
if(dp[i][j][k] < INF) {
ans = max(ans, bits1[j]);
}
}
}
}
cout << ans << endl;
}
return 0;
}
uva10857(状态压缩DP)的更多相关文章
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- [知识点]状态压缩DP
// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...
- HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP
题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...
- DP大作战—状态压缩dp
题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...
- 状态压缩dp问题
问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
- Marriage Ceremonies(状态压缩dp)
Marriage Ceremonies Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu ...
- HDU 1074 (状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...
随机推荐
- 《Cracking the Coding Interview》——第4章:树和图——题目3
2014-03-19 03:34 题目:给定一个排好序的数组,设计算法将其转换为一棵二叉搜索树,要求树的高度最小. 解法:递归生成平衡二叉树,使左右子树的节点数尽量相等,所以对半开最好了.其实也可以生 ...
- 【Linear Regression】林轩田机器学习基石
这一节开始讲基础的Linear Regression算法. (1)Linear Regression的假设空间变成了实数域 (2)Linear Regression的目标是找到使得残差更小的分割线(超 ...
- 【Substring with Concatenation of All Words】cpp
题目: You are given a string, s, and a list of words, words, that are all of the same length. Find all ...
- js对象使用
以下是js对象使用的两种方式 <script type="text/javascript"> var people = function () { } //方法1 pe ...
- 【Python】Django学习一:第一个Django程序
项目开发环境 Python 3.6 Django 1.11.5 Django安装 在开始安装Django之前,Django更新比较频繁,所以要选择合适的版本,这里选择Django1.11.5. pip ...
- Python 3基础教程10-全局变量和局部变量
本文来讲讲全局变量和局部变量,前面学习了函数的基本使用,所以,这里就要注意变量的使用和访问权限. 试试下面的demo.py
- 孤荷凌寒自学python第十八天python变量的作用范围
孤荷凌寒自学python第十八天python函数的形参与变量的范围 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.在python的函数中各种不同的形式参数在定义的先后顺序上有规定: 必须 ...
- 【Android】Android中期项目设计题目-界面设计小作业-提交截止时间2016.4.8
评选三份作品,请发关于app运行界面截图的博客.
- 【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫 最小环套树森林
题目描述 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个 ...
- log4j的各种类的配置
log4j看上去像是一种简单的,易配置的日志打印技术.但是实际使用的时候发现,还有各种很相似的日志技术.很多地方的配置一乱就不知道怎么对应了.所以应该把log4j的一切做个简单的分类记录. (一)ja ...