PKU1011 Sticks 经典DFS(TLE了。。没办法)
2009-03-20 01:16
429 查看
/*
Sticks
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 48226 Accepted: 10568
Description
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
Input
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.
Output
The output should contains the smallest possible length of original sticks, one per line.
Sample Input
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
Sample Output
6
5
Source
Central Europe 1995*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
int cmp(int a,int b)
{
return a > b;
}
int used[100] = {0};
int sticks = 0;
int singlesum = 0;
void smallsolution(int number,int length,vector<int> iput)
{
if(sticks == number)
{
return;
}
else if(singlesum == length)
{
sticks++;
singlesum = 0;
for(int k = 0;k < iput.size();k++)
{
if(used[k] == 2)
{
used[k] = 0;
}
}
smallsolution(number,length,iput);
if(sticks == number)
{
return;
}
sticks--;
singlesum = length;
for(int k = 0;k < iput.size();k++)
{
if(used[k] == 2)
{
used[k] = 0;
}
}
}
else
{
for(int i = 0,per = -1;i < iput.size();i++)
{
if(used[i] == 0 && iput[i] != per && iput[i] + singlesum <= length)
{
per = iput[i];
singlesum = singlesum + iput[i];
used[i] = 1;
smallsolution(number,length,iput);
if(sticks == number)
{
return;
}
else
{
singlesum = singlesum - iput[i];
used[i] = 2;
}
}
}
}
return;
}
int solution(vector<int> iput)
{
int sum = 0;
int number;
sort(iput.begin(),iput.end(),cmp);
for(vector<int> :: const_iterator iter = iput.begin();iter != iput.end();iter++)
{
sum = sum + (*iter);
}
for(int length = (*iput.begin());length <= sum;length++)
{
if(sum % length == 0)
{
number = sum / length;
smallsolution(number,length,iput);
if(sticks == number)
{
sticks = 0;
memset(used,0,100*sizeof(int));
return length;
}
else
{
sticks = 0;
memset(used,0,100*sizeof(int));
}
}
}
}
int main(void)
{
int parts;
while(cin>>parts)
{
if(parts > 0)
{
vector<int> iput;
int tmp;
for(int i = 0;i < parts;i++)
{
cin>>tmp;
iput.push_back(tmp);
}
cout<<solution(iput)<<endl;
}
else
{
break;
}
}
return 0;
}
艾挑战失败。。不过好歹不是WA。。。。。。。。。DISCUSS里这组BT数据
Sticks
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 48226 Accepted: 10568
Description
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
Input
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.
Output
The output should contains the smallest possible length of original sticks, one per line.
Sample Input
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
Sample Output
6
5
Source
Central Europe 1995*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
int cmp(int a,int b)
{
return a > b;
}
int used[100] = {0};
int sticks = 0;
int singlesum = 0;
void smallsolution(int number,int length,vector<int> iput)
{
if(sticks == number)
{
return;
}
else if(singlesum == length)
{
sticks++;
singlesum = 0;
for(int k = 0;k < iput.size();k++)
{
if(used[k] == 2)
{
used[k] = 0;
}
}
smallsolution(number,length,iput);
if(sticks == number)
{
return;
}
sticks--;
singlesum = length;
for(int k = 0;k < iput.size();k++)
{
if(used[k] == 2)
{
used[k] = 0;
}
}
}
else
{
for(int i = 0,per = -1;i < iput.size();i++)
{
if(used[i] == 0 && iput[i] != per && iput[i] + singlesum <= length)
{
per = iput[i];
singlesum = singlesum + iput[i];
used[i] = 1;
smallsolution(number,length,iput);
if(sticks == number)
{
return;
}
else
{
singlesum = singlesum - iput[i];
used[i] = 2;
}
}
}
}
return;
}
int solution(vector<int> iput)
{
int sum = 0;
int number;
sort(iput.begin(),iput.end(),cmp);
for(vector<int> :: const_iterator iter = iput.begin();iter != iput.end();iter++)
{
sum = sum + (*iter);
}
for(int length = (*iput.begin());length <= sum;length++)
{
if(sum % length == 0)
{
number = sum / length;
smallsolution(number,length,iput);
if(sticks == number)
{
sticks = 0;
memset(used,0,100*sizeof(int));
return length;
}
else
{
sticks = 0;
memset(used,0,100*sizeof(int));
}
}
}
}
int main(void)
{
int parts;
while(cin>>parts)
{
if(parts > 0)
{
vector<int> iput;
int tmp;
for(int i = 0;i < parts;i++)
{
cin>>tmp;
iput.push_back(tmp);
}
cout<<solution(iput)<<endl;
}
else
{
break;
}
}
return 0;
}
艾挑战失败。。不过好歹不是WA。。。。。。。。。DISCUSS里这组BT数据
64 40 40 30 35 35 26 15 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 25 39 46 40 10 4 40 40 37 18 17 16 15 40 40 40 40 40 40 40 454 一堆AC的人喊要花N秒钟才出来我可是刷了一下就出来结果了。。。无语阿 题目本身的话。。。DFS,USED数组表示状态。。一定要记住DFS着色的三种状态。。也就是白 灰 黑(不明白的看 算法导论里DFS那章)。。对应我的代码就是0,1,2。。刚开始的时候把DFS最关键的三状态给忽视了只设了2个 状态。。巨大的教训阿。。。。。。。以后要记住凡是DFS都要三状态= =。。。 然后就是状态的还原等问题了。。。估计我就是这里没弄好才TLE了。。因为2状态清除的时候我遍历了整个数组 而且还是2次。。。这里可能可以作个优化吧
相关文章推荐
- poj 1011 Sticks (经典dfs)
- poj 1011 Sticks - 经典DFS
- POJ 1011 Sticks (DFS +强力剪枝 (经典))
- poj 1011 Sticks(经典搜索问题:DFS+剪枝)
- hdu1455 && poj1011 Sticks(深度优先搜索 DFS 经典剪枝 详解)
- PKU-1011 Sticks (DFS + 剪枝)
- POJ 1011 Sticks (经典DFS)
- 搜索剪枝回溯经典题目 pku 1011 sticks
- poj 1011 Sticks 经典的深搜(dfs)+ 强剪枝
- POJ 1011 Sticks(经典dfs)
- hdu 1455/poj 1011 Sticks(DFS剪枝神题)
- Sticks (dfs经典剪枝)
- poj 1011 Sticks【dfs】
- 【DFS搜索】poj1011 Sticks
- POJ1011 Sticks【DFS+剪枝】
- poj入门水题--深度搜索(dfs)题 1011,含各种剪枝,比较经典
- PKU 1011 Sticks
- pku 1011(dfs)
- POJ 1011 Sticks(DFS + 剪枝)
- [POJ 1011]Sticks(DFS剪枝)