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}{红}}\) 色. 题单 (刷过的 ...
随机推荐
- HTML5新增属性data-*和js/jquery之间的交互
HTML5新增属性data- data-自定义属性,这种方式的自定义属性解决属性混乱无状态管理的现状 书写实例 <div data-role="page" data-last ...
- Windows 2012建立域控(AD DS)详解
Active Directory概述: 使用 Active Directory(R) 域服务 (AD DS) 服务器角色,可以创建用于用户和资源管理的可伸缩.安全及可管理的基础机构, ...
- VB与C#语言部分不用的地方Part1
1. 数据类型: ① 日期型(Date) 表示日期和时间用两个“#”符号把日期和时间的值括起来,如:#08/20/2001#.#2001-08-20#. ② 变体型(Variant) ...
- 【ACM小白成长撸】--计算单词个数
我判断单词个数的方法,根据空格‘ ’的个数 分情况 当没有单词的时候 判断第一个符号,即a[0] == ‘\0’时,赋值给存储个数的数组 当遇到空格时,只有前面一个字符不是空格字符,后面一个字符不是空 ...
- 没有闲话和grunt.initConfig()
grunt.initConfig()为Gruntfile.js的核心部分,它接收对象作为参数. 对象包含两种类型的属性,一种是单纯的变量,一种是task类型.举个栗子: grunt.initConfi ...
- C# 模拟网站登陆并截图
1.在窗体上加一个按钮,为按钮添加点击事件 private void button1_Click(object sender, EventArgs e) { Bitmap m_Bitmap = Web ...
- 团队作业3-需求改进&原型设计
选题:实验室报修系统 实验室设备经常会发生这样或那样的故障,靠值班人员登记设备故障现象,维护人员查看故障记录,进行维修,然后登记维修过程与内容,以备日后复查,用这种方式进行设备运营管理,它仅仅起到一个 ...
- 201521123085 《Java程序设计》第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1) 1.1 实验总结 要注意到在删除元素 ...
- 201521123078 《java》第五周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句 ...
- 201521123073 《Java程序设计》第1周学习总结
1.本章学习总结 你对于本章知识的学习总结 1.Java中使用Scanner处理输入,需要注意如下几个地方 程序开头必须import java.util.Scanner导入Scanner类. 使用Sc ...