poj 1011 解题报告
来源:互联网 发布:软件方面的证书 编辑:程序博客网 时间:2024/06/10 17:22
被这个题困扰了几天,开始的时候用贪心,速度很快但是结果WA,贪心不可以的原因是没有搜索到所有可能的结果集,长优先并不一定是最好的结果。
后来用深度优先搜索+剪枝 结果TLE,郁闷了半天开始优化剪枝,直到AC, 结果还是花了32MS,不知道那些0MS的大牛们怎么优化出来的,反正我是快崩溃了,不想再整这个题了。
首先说一下这个题的解题思想。
1.选取某一个开始长度,开始组合小木棒,这个开始长度的限制条件为 不小于木棒最大长度,不大于所有木棒长度和,能被长度和整除
2.从可用的最长的那根小木棒开始组合木棒,找出所有的结果集,找到结果集后开始组合下一根木棒。
3.直到所有的小木棒都被组合完成,搜索结束。
- #include <cstdlib>
- #include <iostream>
- #include <vector>
- #include <algorithm>
- using namespace std;
- int sticksNum; //木棒个数
- int totalLen; //总长度
- int caseNum; //应该组合得到的木棒数
- vector<int> sticks;//存放小木棒长度
- vector<int> used;//记录木棒使用状态
- bool searchSticks(int index,int len,int complete);
- bool searchResult(int index,int nowLen,int len,int start,int complete) //从index开始 搜索长度为len 完成长度为 nowLen 木棒 complete 已完成数
- {
- if(nowLen==len)
- {
- return (searchSticks(start-1,len,complete+1));
- }
- else if(nowLen>len) //优化 若当前长度大于总长度 不符合条件
- {
- return false;
- }
- if(index==-1)
- if(nowLen==len)
- return (searchSticks(start-1,len,complete+1));
- else
- return false;
- if(index==0)
- {
- if(used[index]==0)
- {
- if(nowLen==0)
- {
- return (searchSticks(start-1,len,complete+1));
- }
- else
- {
- return false;
- }
- }
- else
- {
- if(nowLen+sticks[0]!=len)
- return false;
- else
- {
- used[index]=0;
- if(searchSticks(start-1,len,complete+1))
- {
- return true;
- }
- else
- {
- used[index]=1;
- return false;
- }
- }
- }
- }
- if(used[index]==0)
- {
- return searchResult(index-1,nowLen,len,start,complete);
- }
- else
- {
- if(nowLen+sticks[index]>len)
- return searchResult(index-1,nowLen,len,start,complete);
- else if(nowLen+sticks[index]==len)
- {
- used[index]=0;
- if(searchSticks(start-1,len,complete+1))
- {
- return true;
- }
- else
- {
- used[index]=1;
- return false;
- }
- }
- else
- {
- int tempLen=0;
- for(int i=index;i>=0;--i)
- {
- if(tempLen==sticks[i]||used[i]==0) //优化 若该小木棒已被用过 或前面小木棒长度和它相同 则没必要再搜索下去
- continue;
- tempLen=sticks[i];
- used[i]=0;
- if(searchResult(i-1,nowLen+tempLen,len,start,complete))
- {
- return true;
- }
- else
- {
- used[i]=1;
- }
- }
- return false;
- }
- }
- }
- bool searchSticks(int index,int len,int complete)//组合以index开始的木棒
- {
- if(index==-1)
- return true;
- if(used[index]==0)
- return searchSticks(index-1,len,complete);
- if((caseNum-complete)>(index+1)) //优化:若还应该组合得到的木棒数大于当前剩余的小木棒数 则不符合条件
- return false;
- int nowLen=sticks[index];
- if(nowLen==len)
- {
- used[index]=0;
- if(searchSticks(index-1,len,complete+1))
- {
- return true;
- }
- else
- {
- used[index]=1;
- return false;
- }
- }
- used[index]=0;
- if(searchResult(index-1,nowLen,len,index,complete))
- {
- return true;
- }
- else
- {
- used[index]=1;
- return false;
- }
- }
- int main(int argc, char *argv[])
- {
- while(cin>>sticksNum&&sticksNum!=0)
- {
- totalLen=0;
- int tempLen;
- used.clear();
- sticks.clear();
- for(size_t index=0;index<sticksNum;++index)
- {
- cin>>tempLen;
- totalLen+=tempLen;
- sticks.push_back(tempLen);
- }
- sort(sticks.begin(),sticks.end()); //优化:从小到大排列木棒 大木棒在搜索过程中享有优先权
- int startLen=sticks[sticksNum-1];
- for(int len=startLen;len<=totalLen;++len) //优化 搜索从小木棒最大长度开始
- {
- if(totalLen%len==0)//优化 只有能被总长度整除的长度 才合法
- {
- caseNum=totalLen/len;
- used=vector<int>(sticksNum,1);
- if(searchSticks(sticksNum-1,len,0))
- {
- cout<<len<<endl;
- break;
- }
- }
- }
- }
- // system("PAUSE");
- return EXIT_SUCCESS;
- }
附一组测试数据
915 3 2 11 4 1 8 8 866 2 2 4 8 851 1 1 1 1 21 142 2 9 931 2 36440 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 43 42 42 41 10 4 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 749 48 47 46 45 44 4373 4 5 5 5 5 1372 7 7 7 7 10 2061 2 3 11 11 20763 2 44 12 60 35 60 95 2 1 5 2 1 5 2 141 2 3 40//答案:15 11 8 8 8 4 3 2 1第1 of 3根木棍:15+3+2=20第2 of 3根木棍:11+8+1=20第3 of 3根木棍:8+8+4=20第1组测试数据结果:208 8 6 4 2 2第1 of 3根木棍:8+2=10第2 of 3根木棍:8+2=10第3 of 3根木棍:6+4=10第2组测试数据结果:101 1 1 1 1第3组测试数据结果:11 1第4组测试数据结果:19 9 2 2第1 of 2根木棍:9+2=11第2 of 2根木棍:9+2=11第5组测试数据结果:113 2 1第2 of 2根木棍:2+1=3第6组测试数据结果:364个BT数字:第1 of 2根木棍:43+42+42+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+4=1251第2 of 2根木棍:41+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+40+10=1251第7组测试数据结果:125149 48 47 46 45 44 43第1 of 1根木棍:49+48+47+46+45+44+43=322第8组测试数据结果:32213 5 5 5 5 4 3第1 of 2根木棍:13+4+3=20第2 of 2根木棍:5+5+5+5=20第9组测试数据结果:2020 10 7 7 7 7 2第1 of 2根木棍:20+10=30第2 of 2根木棍:7+7+7+7+2=30第10组测试数据结果:3020 11 11 3 2 1第1 of 2根木棍:20+3+1=24第2 of 2根木棍:11+11+2=24第11组测试数据结果:2463 60 60 44 35 12 2第1 of 1根木棍:63+60+60+44+35+12+2=276第12组测试数据结果:2765 5 5 2 2 2 1 1 1第1 of 4根木棍:5+1=6第2 of 4根木棍:5+1=6第3 of 4根木棍:5+1=6第4 of 4根木棍:2+2+2=6第13组测试数据结果:64 3 2 1第1 of 2根木棍:4+1=5第2 of 2根木棍:3+2=5第14组测试数据结果:5
- poj 1011 解题报告
- Poj 1011 解题报告
- 解题报告 poj 1011 木棒
- POJ 1011 Sticks 解题报告
- POJ 1011 Sticks 解题报告
- poj 1011 Sticks解题报告【DFS+剪枝】
- poj数百篇解题报告
- poj 1141解题报告
- poj 1001解题报告
- poj 1087 解题报告
- poj 2153解题报告
- poj 2051解题报告
- POJ 1167 解题报告
- poj 1026 解题报告
- POJ 1077 解题报告
- POJ 1042 解题报告
- POJ 1095 解题报告
- POJ 1159解题报告
- SQL语法参考
- MapXtreme2005(WebGis)+C#.Net2.0从入门到精通之:For absolute beginner(1)
- GUI测试总结
- 在asp.net的Web表单间传值
- 进行软件架构设计的益处
- poj 1011 解题报告
- JPEG 原理详细实例分析及其在嵌入式 Linux 中的应用
- 配置Tomcat数据源和连接池
- keytool生成证书 查看证书信息 ,以及java操作的简单用例
- Linux 包管理速查表
- 万一的 Delphi 博客
- DOS 和Unix 文件--vim转化
- 第一天开通
- 软件架构的过程