poj 1011 dfs+剪枝

据说是剪枝神题,不过剪枝确实是挺多的,少一个有可能都会超时。

 1 #include <algorithm>

 2 #include <cstring>

 3 #include <cstdio>

 4 using namespace std;

 5 

 6 const int N = 100;

 7 int stick[N];

 8 bool used[N];

 9 int n, snum, slen;

10 

11 bool dfs( int num, int len, int pos )

12 {

13     if ( num == snum ) return true;

14     for ( int i = pos; i < n; i++ )

15     {

16         if ( !used[i] )

17         {

18             int tmp = stick[i] + len;

19             if ( tmp > slen ) continue;

20             used[i] = 1;

21             if ( tmp == slen )

22             {

23                 if ( dfs( num + 1, 0, 0 ) ) return true;

24                 used[i] = 0;

25                 return false;

26             }

27             else

28             {

29                 if ( dfs( num, tmp, i + 1 ) ) return true;

30                 used[i] = 0;

31             }

32             if ( len == 0 ) return false;

33             while ( stick[i] == stick[i + 1] ) i++;

34         }

35     }

36     return false;

37 }

38 

39 bool cmp( int a, int b )

40 {

41     return a > b;

42 }

43 

44 int main ()

45 {

46     while ( scanf("%d", &n), n )

47     {

48         int sum = 0;

49         for ( int i = 0; i < n; i++ )

50         {

51             scanf("%d", stick + i);

52             sum += stick[i];

53         }

54         sort( stick, stick + n, cmp );

55         stick[n] = -1;

56         int maxn = stick[0];

57         for ( int i = maxn; i <= sum; i++ )

58         {

59             if ( sum % i == 0 )

60             {

61                 snum = sum / i;

62                 slen = i;

63                 memset( used, 0, sizeof(used) );

64                 if ( dfs( 0, 0, 0 ) )

65                 {

66                     printf("%d\n", i);

67                     break;

68                 }

69             }

70         }

71     }

72     return 0;

73 }

 

你可能感兴趣的:(poj)