您的位置:首页 > 其它

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数据

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次。。。这里可能可以作个优化吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: