【Luogu】【关卡2-9】带有技巧的搜索(2017年10月)
任务说明:这里的搜索不仅包含了dfs和bfs,还包括剪枝、记录等技巧以加快速度。
[USACO06FEB]数字三角形Backward Digit Su…
滑雪
吃奶酪
靶形数独
P1118 [USACO06FEB]数字三角形Backward Digit Su…
有这么一个游戏:写出一个1~N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置。
最后得到16这样一个数字。
现在想要倒着玩这样一个游戏,如果知道N,知道最后得到的数字的大小sum,请你求出最初序列a[i],为1~N的一个排列。若答案有多种可能,则输出排序最小的那一个。
解答:第一次我想直接next_permutation,然后在嵌套循环计算顶层数字,结果TLE了好几个点。
后来看了题解,大家都说的杨辉三角,我还是没懂。专门搜索了题解才看懂。
最后的结果其实是一个杨辉三角。(拿样例来说,第4层的杨辉三角是1 3 3 1; 1∗3+3∗1+3∗2+1∗4=16)
然后知道杨辉三角怎么用了之后,直接dfs求全排列,如果超过了sum值就回溯。
#include <bits/stdc++.h>
#include <string>
using namespace std; int n, sum;
int yanghuisanjiao[][] = {};
int used[] = {}; void print(vector<int>& vec, std::string& strDes) {
printf("%s: ", strDes.c_str());
for (int i = ; i < vec.size(); ++i) {
printf("%d ", vec[i]);
}
printf("\n");
} void print(vector<int>& vec) {
for (int i = ; i < vec.size(); ++i) {
printf("%d ", vec[i]);
}
printf("\n");
} bool dfs(int level, vector<int>& permutation, int cal_sum, int idx) {
if (level == n + ) {
if (cal_sum == sum) {
print(permutation);
return true;
}
return false;
}
for (int i = ; i < n; ++i) {
if (!used[i+]) {
permutation[idx] = i + ;
used[i+] = ;
//如果求和大于sum,就剪枝
if (cal_sum + yanghuisanjiao[n-][idx] * permutation[idx] > sum) {
used[i+] = false;
return false;
}
bool ans = dfs(level + , permutation, cal_sum + yanghuisanjiao[n-][idx] * permutation[idx], idx + );
if (ans == true) {
return true;
}
used[i+] = ;
}
}
//找到最后也没找到, 就return false
return false;
} int main() {
cin >> n >> sum; //[1]计算杨辉三角
for (int i = ; i < n ; ++i) {
for (int j = ; j <= i; ++j) {
if (j == || j == i ) {
yanghuisanjiao[i][j] = ;
}
else {
yanghuisanjiao[i][j] = yanghuisanjiao[i-][j-] + yanghuisanjiao[i-][j];
}
}
} //[2]深搜求全排列
vector<int> permutation(n, );
dfs(, permutation, , );
return ;
}
P1433 吃奶酪
房间里放着n块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处。
输入:第一行一个数n (n<=15),接下来每行2个实数,表示第i块奶酪的坐标。两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
输出:一个数,表示要跑的最少距离,保留2位小数。
题解:显然贪心不行。那么只能搜索每个点的顺序,求最小值的距离。
//这个题目最后也是90分,第五个点TLE,没想明白为啥
#include<bits/stdc++.h>
#include<unistd.h>
#include <sys/time.h>
using namespace std; typedef pair<double, double> P;
int n; double ans = DBL_MAX;
int addx[] = {, -, , };
int addy[] = {-, , , }; void print(vector<vector<double>> vec) {
printf("===============debug============\n");
for (int i = ; i < vec.size(); ++i) {
for(int j = ; j < vec.size(); ++j) {
printf("%.2f ", vec[i][j]);
}
printf("\n");
}
printf("===============end==============\n");
} void dfs(const vector<P>& coor, const double dis[][], vector<int>& used, int level, double tmpans, int pre) {
if (tmpans >= ans) {
return;
}
if (level == coor.size()) {
if (ans > tmpans) { ans = tmpans;}
return;
}
for(int i = ; i < coor.size(); ++i) {
double temp = dis[pre][i] + tmpans;
if (!used[i] && temp < ans) {
used[i] = ;
dfs(coor, dis, used, level+, temp, i);
used[i] = ;
}
}
} int main() {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("%ld\n", tv.tv_sec);
scanf("%d", &n);
vector<P> coor(n + );
coor[] = make_pair(0.0, 0.0);
for(int i = ; i <= n; ++i){
double x, y;
scanf("%lf %lf", &x, &y);
coor[i] = make_pair(x, y);
} double dis[][] = {0.0};
for(int i = ; i <= n; ++i) {
for(int j = i; j <= n; ++j) {
dis[i][j] = dis[j][i]
= sqrt((coor[i].first - coor[j].first)*(coor[i].first - coor[j].first)
+ (coor[i].second - coor[j].second)*(coor[i].second - coor[j].second));
}
} vector<int> use(n+);
use[] = ;
dfs(coor, dis, use, , 0.0, );
printf("%.2f\n", ans);
gettimeofday(&tv, NULL);
printf("%ld\n", tv.tv_sec);
return ;
}
【Luogu】【关卡2-9】带有技巧的搜索(2017年10月)的更多相关文章
- 【Luogu】【关卡2-15】动态规划的背包问题(2017年10月)【还差一道题】
任务说明:这是最基础的动态规划.不过如果是第一次接触会有些难以理解.加油闯过这个坎. 01背包二维数组优化成滚动数组的时候有坑有坑有坑!!!必须要downto,downto,downto 情景和代码见 ...
- 【Luogu】【关卡2-11】简单数学问题(2017年10月)【还差三道题】
火星人 麦森数 P1403 [AHOI2005]约数研究 f(n)表示n的约数个数,现在给出n,要求求出f(1)到f(n)的总和. 解答:有几个1做约数的个数 = n /1; 有几个2做约数的个数 = ...
- 【Luogu】【关卡2-1】简单的模拟(2017年10月)
任务说明:开始普及组的训练!所谓模拟,就是直接根据题意编写,思维难度简单. 铺地毯 进制转换 多项式输出 机器翻译 排座椅 笨小猴 都是简单模拟题
- 【Luogu】【关卡2-8】广度优先搜索(2017年10月)
任务说明:广度优先搜索可以用来找有关“最短步数”的问题.恩,也可以用来“地毯式搜索”.
- 【Luogu】【关卡2-7】深度优先搜索(2017年10月)【AK】【题解没写完】
任务说明:搜索可以穷举各种情况.很多题目都可以用搜索完成.就算不能,搜索也是骗分神器. P1219 八皇后 直接dfs.对角线怎么判断:同一条对角线的横纵坐标的和或者差相同. #include < ...
- 【Luogu】【关卡2-4】排序Ex(2017年10月)
任务说明:这里的排序就更上一层了.不仅融合了别的算法与技巧,排序本身也有各种花招.
- 【Luogu】【关卡1-8】BOSS战-入门综合练习2(2017年10月)【AK】------都是基础题
P1426 小鱼会有危险吗 我个人觉得这个题目出的不好,没说明白,就先只粘贴的AC代码吧 #include <bits/stdc++.h> using namespace std; int ...
- 【Luogu】【关卡2-16】线性动态规划(2017年10月)【还差三道题】
任务说明:这也是基础的动态规划.是在线性结构上面的动态规划,一定要掌握. P1020 导弹拦截 导弹拦截 P1091 合唱队形 老师给同学们排合唱队形.N位同学站成一排,音乐老师要请其中的(N-K)位 ...
- 【Luogu】【关卡2-14】 树形数据结构(2017年10月)【AK】
任务说明:由一个根节点分叉,越分越多,就成了树.树可以表示数据之间的从属关系 P1087 FBI树 给一个01字符串,0对应B,1对应I,F对应既有0子节点又有1子节点的根节点,输出这棵树的后序遍历. ...
随机推荐
- shell变量及相关命令
- go语言从例子开始之Example9.切片
Slice 是 Go 中一个关键的数据类型,是一个比数组更加强大的序列接口 package main import "fmt" func main() { 不像数组,slice 的 ...
- Android 混淆总结(直接copy)(转)
转自:http://blog.csdn.net/u012188405/article/details/51985273 # Add project specific ProGuard rules he ...
- Oracle修改数据文件路径
更改Oracle数据文件名及数据文件存放路径 SQL> select * from v$dbfile; FILE# NAME---------- ------------------- ...
- git 初始化提交项目
Git初始化本地已有项目,并推送到远端Git仓库操作1. 创建本地项目,在项目根目录执行git init命令git init 2. 在git服务器上创建一个仓库,这里使用GitHub创建一个仓库.例如 ...
- C语言数组,指针小案例
/* ============================================================================ Name : hello.c Autho ...
- c++11 继承构造函数
若基类拥有数量众多的不同版本的构造函数,而派生类中只有一些成员函数,则对于派生类而言,其构造函数就等同于构造基类. struct A { A(int i) {} A(double d, int i) ...
- 【多线程】ConcurrentLinkedQueue 的实现原理
1. 引言 在并发编程中我们有时候需要使用线程安全的队列.如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把 ...
- MySQL 时间戳与日期格式的相互转换(转)
1.UNIX时间戳转换为日期用函数: FROM_UNIXTIME() select FROM_UNIXTIME(1156219870); 输出:2006-08-22 12:11:10 2.日期转换为U ...
- PHP-模拟请求和操作响应
模拟请求 fsockopen <?php // 建立连接 $link = fsockopen('localhost', '80'); define('CRLF', "\r\n" ...