codeforces 8c Looking for Order
https://vjudge.net/problem/CodeForces-8C
题意:
一个平面上放着许多东西,每个东西都有一个坐标,最开始一个人在一个起始坐标,她出发去拿东西,一次要么拿一件东西,要么拿两件东西,拿了之后必须返回起始坐标。
每次花费的时间是两个坐标距离的平方,问拿完所有的东西需要的最少的时间。
思路:
由于数据范围比较小,所以可以考虑用状压dp来写。由于每次拿东西之后都要返回起点,那么其实拿东西的顺序是没有影响的,所以利用题目给定的顺序进行剪枝,即每次进行扩展的时候都考虑在前面的点已经取完了。
然后每次记录的时候,非常巧妙的方法,如果一个点的话,直接记录这个点,如果有两个点的话,那么就用(i+1)*100 + (j+1)来记录,因为点数最多时只有24,输出的时候递归输出就行了,递归输出这里还是比较巧妙的。
代码:(有详细的注释)
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std; struct node
{
int x,y;
} a[]; int mp[][];
vector<int> ans; int cal(int i,int j)
{
return (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y);
} const int maxn = ( << )+;
const int gg = 0x3f3f3f3f; int dp[maxn],last[maxn],rec[maxn]; void output(int s)
{
if (~last[s])
output(last[s]);//递归输出 if (rec[s])
{
if (rec[s] > ) ans.push_back(rec[s] / );//第一个扩展的点 ans.push_back(rec[s] % );
ans.push_back();//每次都要返回起点
}
} int main()
{
int n; node tmp; scanf("%d%d",&tmp.x,&tmp.y); scanf("%d",&n); for (int i = ;i < n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
} a[n] = tmp; for (int i = ;i <= n;i++)
for (int j = i + ;j <= n;j++)
mp[i][j] = mp[j][i] = cal(i,j); memset(dp,gg,sizeof(dp));
memset(last,-,sizeof(last)); dp[] = ; for (int s = ;s < (<<n);s++)
{
if (dp[s] >= gg) continue; for (int i = ;i < n;i++)
{
if ((( << i) & s) == )//这个点没有被走过
{
int val = dp[s] + mp[n][i] * ; if (dp[s|( << i)] > val)
{
dp[s|( << i)] = val;
last[s|( << i)] = s;//记录前驱,下同
rec[s|( << i)] = i+;
} for (int j = i + ;j < n;j++)//从i+1开始枚举保证了不会有重复情况
{
if (((<<j)&s) == )
{
int tmp = dp[s] + mp[n][i] + mp[i][j] + mp[j][n]; if (dp[s|(<<i)|(<<j)] > tmp)
{
dp[s|(<<i)|(<<j)] = tmp;
last[s|(<<i)|(<<j)] = s;
rec[s|(<<i)|(<<j)] = (i+) * + (j+);//巧妙的记录
}
}
} break;//强行顺序剪枝
}
} //printf("%d\n",dp[s]);
} ans.clear(); output((<<n)-); printf("%d\n",dp[(<<n)-]); printf("0 "); for (int i = ;i < ans.size();i++)
printf("%d%s",ans[i],i == ans.size() - ? "\n" :" "); return ;
}
codeforces 8c Looking for Order的更多相关文章
- codeforces 8C. Looking for Order 状压dp
题目链接 给n个物品的坐标, 和一个包裹的位置, 包裹不能移动. 每次最多可以拿两个物品, 然后将它们放到包里, 求将所有物品放到包里所需走的最小路程. 直接状压dp就好了. #include < ...
- 【题解】codeforces 8c Looking for Order 状压dp
题目描述 Lena喜欢秩序井然的生活.一天,她要去上大学了.突然,她发现整个房间乱糟糟的--她的手提包里的物品都散落在了地上.她想把所有的物品都放回她的手提包.但是,这里有一点问题:她一次最多只能拿两 ...
- Codeforces 993E Nikita and Order Statistics [FFT]
洛谷 Codeforces 思路 一开始想偏想到了DP,后来发现我SB了-- 考虑每个\(a_i<x\)的\(i\),记录它前一个和后一个到它的距离为\(L_i,R_i\),那么就有 \[ an ...
- codeforces 637B B. Chat Order(map,水题)
题目链接: B. Chat Order time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
- codeforces 8C(非原创)
C. Looking for Order time limit per test 4 seconds memory limit per test 512 megabytes input standar ...
- [Codeforces 993E]Nikita and Order Statistics
Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,和一个数 \(x\) ,对于每个 \(i= 0\sim n\) ,求有多少个非空子区间满足恰好有 \(i\) 个数 ...
- Codeforces 8C 状压DP
题意:有个人想收拾行李,而n个物品散落在房间的各个角落里(n < 24).现在给你旅行箱的坐标(人初始在旅行箱处),以及n个物品的坐标,你一次只能拿最多两个物品,并且拿了物品就必须放回旅行箱,不 ...
- [CF] 8C Looking for Order
状压模板题 CF难度2000? 我得好好了解一下CF的难度机制了 反正CF的难度比洛谷真实就好了 Code #include<algorithm> #include<iostream ...
- CF dp 题(1500-2000难度)
前言 从后往前刷 update 新增 \(\text{\color{red}{Mark}}\) 标记功能,有一定难度的题标记为 \(\text{\color{red}{红}}\) 色. 题单 (刷过的 ...
随机推荐
- 服务端性能测试 TPS
针对服务器端的性能,以TPS为主来衡量系统的性能,并发用户数为辅来衡量系统的性能,如果必须要用并发用户数来衡量的话,需要一个前提,那就是交易在多长时间内完成,因为在系统负载不高的情况下,将思考时间( ...
- Linux io Model
socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调 ...
- 自己动手写fullPage插件
仿造fullPage.js https://alvarotrigo.com/fullPage/#firstPage 自己参照网上教程写了一个,加了注释.主要是练习造轮子的能力,需求是不断变化的只拿来用 ...
- 学习之-ASP.NET MVC Filter
MVC Filter 是典型的AOP应用,对MVC框架处理客户端请求注入额外的一些逻辑,如日志记录.缓存处理.异常处理和权限验证,性能检测(横切关注点),而这些逻辑通常与主要业务无关,被独立分开作为公 ...
- 数据结构学习:KMP模式匹配算法
有关KMP的算法具体的实现网上有很多,不具体阐述.这里附上c的实现. 谈谈我自己的理解.KMP相较于朴素算法,其主要目的是为了使主串中的遍历参数i不回溯,而直接改变目标串中的遍历参数j. 比如说要是目 ...
- 嵌套ajax 页面卡死的问题
问题:要一个AJAX中的回调函数中又进行了一个AJAX调用,并且这个AJAX是在一个循环调用的,不论设置async属性是true和false页面卡死. 解决方法:async属性都设为true,不用循环 ...
- 个人作业3—个人总结(Alpha阶段)
一.个人总结 在Alpha阶段,我们团队通过合作的方式,完成了之前觉得不大可能会完成的事(至少在我看来是这样的),大家其实之前的写代码能力都不太好,这期间大家都是边学边做,边做边学,最后跌跌撞撞的完成 ...
- Java 第十周总结
1. 本周学习总结 2. 书面作业 1.finally (题目4-2) 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? finally创建一个代码块.该代 ...
- 201521123075 《Java程序设计》第14周学习总结
1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) 参 ...
- Linux-exec命令试验驱动(12)
对于做驱动经常会使用exec来试验驱动,通过exec将-sh进程下的描述符指向我们的驱动,来实现调试 -sh进程常用描述符号: 0:标准输入 1:标准输出 2:错误信息 5:中断服务 exec命令使用 ...