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个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...
随机推荐
- python流程控制语句 ifelse - 2
#! /usr/bin/python x = input('please input a integer:') x = int (x) ): print('你输入了一个负数') else: print ...
- 一个zip压缩类,欢迎吐槽
package com.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import j ...
- BIND9配置文件详解模板[转载]
在CU上看到了一篇关于BIND9配置文件详解的文章,感觉不错,现转载了分享一下. //named.conf 注释说明 by shellyxz@163.com// 此文件对bind9的默认配置文件的说明 ...
- group by的SQL语句
有一张项目表 CREATE TABLE [ProjectTable] ( [ProjectID] NVARCHAR(16) NOT NULL, [ProjectName] NVARCHAR(20) N ...
- 函数buf_page_create
/********************************************************************//** Initializes a page to the ...
- CodeForces Round #278 (Div.2) (待续)
A 这么简单的题直接贴代码好了. #include <cstdio> #include <cmath> using namespace std; bool islucky(in ...
- 监听某个div或其它标签的大小改变来执行相应的处理
jquery 默认的resize只能监听到浏览器窗口大小的改变,但我们在实际使用过程中有可能还需要监听某个div或其它标签的大小改变来执行相应的处理,如果使用默认的resize就无能为力了.怎么办呢, ...
- 求强连通分量模板(tarjan算法)
关于如何求强连通分量的知识请戳 https://www.byvoid.com/blog/scc-tarjan/ void DFS(int x) { dfn[x]=lowlink[x]=++dfn_cl ...
- Android精美的日历控件
网上看到的精美日历控件,谨以此文记录一下,用到的时候再来翻翻 源码地址 : http://download.csdn.net/detail/abc13939746593/7265459
- 30种oracle常见的等待事件说明
1Buffer busy waits从本质上讲,这个等待事件的产生仅说明了一个会话在等待一个Buffer(数据块),但是导致这个现象的原因却有很多种.常见的两种是: 当一个会话视图修改一个数据块,但这 ...