UVa 307 - Sticks
| Sticks |
【 随 笔 】:很久之前就遇到这道题,题目意思容易理解,后来自己想到了一个法子,思路也很清晰就将代码敲出来了,用了位运算(后来问师兄是说状态压缩,其实我不知道什么是状态压缩~_~),不过提交的时候超时了,我想着优化代码,尽可能加剪枝的条件,却无从下手,后来搜题解搜到了师兄的博客,题解中剪枝的条件自己能想到的五个中了三个,剩下两个剪枝也容易理解,整个DFS的思路也容易理解,这点值得反思,其中的原因我想是自己先入为主了,在之前的思路上瞎折腾,未果却也不接受考虑另外的可能,其实看了师兄的代码思路后,也就是普普通通的暴力回溯,不多说,先保存TL的代码:
【AC的代码链接】:http://www.cppblog.com/y346491470/articles/155318.html
【超时的代码】
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define MAXN 500
using namespace std;
int sticks[MAXN];
bool visit[MAXN];
int n, sumlen, res; bool judge(int fac)
{
int i;
for(i=; i<n && visit[i]; ++i);
if(i<n) return false;
else
{
res = fac;
return true;
}
} bool Traverse(int fac)
{
for(int i=; i<(<<n); ++i)
{
int subsum = ;
bool is_useful = true;
for(int k=; k<n; ++k)
{
if(i&(<<k))
{
if(visit[k] || subsum > fac)
{
is_useful = false;
break;
}
else subsum += sticks[k];
}
}
if(is_useful && subsum == fac)
{
for(int k=; k<n; ++k)
{
if(i&(<<k)) visit[k] = true;
}
if(judge(fac) || Traverse(fac)) return true;
for(int k=; k<n; ++k)
{
if(i&(<<k)) visit[k] = false;
}
}
}
return false;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("F:\\test\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE
while(cin>>n, n)
{
int curmax = ;
sumlen = ;
for(int i=; i<n; ++i)
{
cin>>sticks[i];
curmax = curmax > sticks[i] ? curmax :sticks[i];
sumlen += sticks[i];
}
for(int fac = curmax; fac <= sumlen; ++fac)
{
if(sumlen%fac == )
{
memset(visit, false, sizeof(visit));
if(Traverse(fac))
{
cout<<res<<endl;
break;
}
}
}
} return ;
}
自己后来又重新写了一遍,写的过程中感觉还是对回溯的理解还是不够深,回溯本是暴力的一种,所以这题也能看到一层一层搜索的路径,没有太多的技巧,都是根据题目的特性找规律,充分利用从而写出剪枝的条件,避免了超时,效率也更高。
【AC代码】
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define MAXN 1000 using namespace std; int sticks[MAXN];
bool visit[MAXN];
int n, length, sum, sumlen; bool cmp(const int& a, const int& b)
{
return a>b;
} bool Traverse(int num, int len, int cur)
{
if(num == sum) return true;
for(int i=cur; i<n; ++i)
{
if(!visit[i] && !(i && !visit[i-] && sticks[i] == sticks[i-]))
{
if(len+sticks[i] == length)
{
visit[i] = true;
if(Traverse(num+, , )) return true;
visit[i] = false;
return false;
}
else if(len+sticks[i] < length)
{
visit[i] = true;
if(Traverse(num, len+sticks[i], i+)) return true;
visit[i] = false;
if(len == ) return false;
}
}
}
return false;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("F:\\test\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE
while(cin>>n, n)
{
int curmax = ;
sumlen = ;
for(int i=; i<n; ++i)
{
cin>>sticks[i];
sumlen += sticks[i];
}
sort(sticks, sticks+n, cmp);
for(int fac = sticks[]; fac <= sumlen; ++fac)
{
if(sumlen%fac == )
{
length = fac;
sum = sumlen/fac;
memset(visit, false, sizeof(visit));
if(Traverse(,,)) break;
}
}
cout<<length<<endl;
} return ;
}
UVa 307 - Sticks的更多相关文章
- POJ 1011 / UVA 307 Sticks
中文题 (一般都比较坑) 思路:DFS (感谢学长的幻灯片) 这破题把我折腾惨了!!!搞了n天 // by Sirius_Ren #include <cstdio> #include &l ...
- Sticks(UVA - 307)【DFS+剪枝】
Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...
- 【Uva 307】Sticks
[Link]: [Description] 给你最多n个棍子; (n< = 64) 每根棍子长度(1..50) 问你这n根棍子,可以是由多少根长度为x的棍子分割出来的; x要求最小 [Solut ...
- uva 307
排序之后再剪枝,有点神 #include <cstdio> #include <cstdlib> #include <cmath> #include <map ...
- 紫书 习题7-14 UVa 307(暴搜+剪枝)
这道题一开始我想的是在排序之后只在头和尾往中间靠近来找木块, 然后就WA, 事实证明这种方法是错误的. 然后参考了别人的博客.发现别人是直接暴搜, 但是加了很多剪枝, 所以不会超时. 我也想过这个做法 ...
- hduoj 1455 && uva 243 E - Sticks
http://acm.hdu.edu.cn/showproblem.php?pid=1455 http://uva.onlinejudge.org/index.php?option=com_onlin ...
- UVA题目分类
题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...
- uva 10003 Cutting Sticks 【区间dp】
题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,事实上和石子归并是一样的 ...
- UVA 10003 Cutting Sticks 区间DP+记忆化搜索
UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...
随机推荐
- 转 Android的消息处理机制
来自:http://blog.csdn.net/andyhuabing/article/details/7368217 Windows编程的朋友可能知道Windows程序是消息驱动的,并且有全局的消息 ...
- [leetcode] Path sum路径之和
要求给定树,与路径和,判断是否存在从跟到叶子之和为给定值的路径.比如下图中,给定路径之和为22,存在路径<5,4,11,2>,因此返回true;否则返回false. 5 / \ 4 8 / ...
- 关于Linux的windows目录的挂载
今天,linux主机下面要增加一点空间,不想再增加硬盘,所以就在实体机里面就设置了目录共享,添加自己系统的默认账号(为了增加自己主机的安全性,我都是设置的含有标点符号的密码---这也是这次挂载不成功的 ...
- mac下装Ruby
https://ruby-china.org/wiki/install_ruby_guide
- 面试题_89_to_92_单元测试 JUnit 面试题
89)如何测试静态方法?(答案)可以使用 PowerMock 库来测试静态方法. 90)怎么利用 JUnit 来测试一个方法的异常?(答案) 91)你使用过哪个单元测试库来测试你的 Java 程序?( ...
- 安卓学习之--如何关闭所有的activity
根据Activity的声明周期 方法1 我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在A窗口打开B窗口时在Intent中直接加入标志 Intent ...
- JSOI2015 分组赛记
分组赛结束了,虽然跟我关系不大,但是去了还是学到了不少东西 day1 上午报到,在宾馆遇到大神wzy,orz 好像没有参赛证发了,于是给我发了一个[工作证],233我是工作人员了,高贵冷艳 下午是常中 ...
- Share SDK分享
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os. ...
- ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking
#!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking # 说明: # 本文主要对TI的s ...
- ES PES TS
1.流媒体系统结构 ES:elemental stream 基本数据流: PES:packet elemental stream分组的基本数据流: 然后把PES打包成PS ,TS流,PS:progra ...