【HDU】 1518 Square
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518
题意很好理解,但是初看的时候功底不深的话(比如我这种菜),不会马上想到用DFS来做的,记得请教ghnjk的时候他突破性的说:emm,这道题目不是背包的思路么?然后dp不好的我只能顿时傻掉:难道是多重背包? ghnjk再仔细看完题目之后,他马上改口了:…… 囧…… 搜索啊,DFS有没有……
顺着DFS的思路可能就会比较好理解,接着我马上写代码,但是还是被卡了一阵子,随后提交的时候,显然是TLE… = =
自己又做了一些优化(都是小剪枝,跟大牛们的思路相比,逊色多了…),变成wa了,囧……(初始的时候是在poj上遇见的,整理的时候就在了HDU上)
没招的情况下,只能求助网上的题解,才发现有题解真的是很好的一件事啊~~ 在此膜拜大神 ORZ~
原来剪枝比我原来想象的要神奇多了!
……(被催去睡觉了,额,未完待续)
贴下写的很辛苦的代码
All Code
1 #include <iostream> 2 #include <map> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <queue> 8 #include <algorithm> 9 #include <ctime> 10 #include <iomanip> 11 #include <fstream> 12 #include <numeric> 13 #include <functional> 14 #include <ctype.h> 15 #define in freopen("in.txt","r",stdin) 16 #define ou freopen("gou.txt","w",stdout) 17 #define INF_MAX 0x7FFFFFFF 18 #define MARK 1e-5 19 #define MAXN 100002 20 using namespace std; 21 int n, stick[25]; 22 bool used[25]; 23 24 int cmp ( const void *a , const void *b ) 25 { 26 return *(int *)b- *(int *)a; 27 } 28 29 bool DFS(int start, int bar, int cur, int &aver) 30 { 31 if(bar==4) return 1; 32 int i, j; 33 for(i=start; i<=n; ++i) if(!used[i]){ 34 if(cur+stick[i]==aver){ 35 used[i]=1; 36 if(DFS(0,bar+1,0,aver)) return 1; 37 used[i]=0; 38 } 39 else if(cur+stick[i]<aver){ 40 used[i]=1; 41 if(DFS(i+1,bar,cur+stick[i],aver)) return 1; 42 used[i]=0; 43 } 44 if(cur==0) break; 45 while(stick[i+1]==stick[i]) i++; 46 //cout<<"~"<<start<<" "<<i<<" "<<stick[i]<<" "<<bar<<" "<<cur<<endl; 47 } 48 return 0; 49 } 50 51 int main() 52 { 53 int i, j, icase, sum, aver; 54 scanf("%d",&icase); 55 while(icase--){ 56 scanf("%d",&n); 57 sum = 0; 58 memset(stick,0,sizeof(stick)); 59 for(i=1; i<=n; ++i) { 60 scanf("%d",&stick[i]); 61 sum += stick[i]; 62 } 63 qsort(stick+1,n,sizeof(stick[1]),cmp); 64 65 aver = sum /4; 66 if(sum%4 || aver<stick[0]){ 67 printf("no\n"); 68 continue; 69 } 70 memset(used,0,sizeof(used)); 71 if(DFS(1,1,0,aver)) printf("yes\n"); 72 else printf("no\n"); 73 } 74 return 0; 75 }