HDU 5937 Equation

题意:
有1~9数字各有a1, a2, …, a9个, 有无穷多的+和=.
问只用这些数字, 最多能组成多少个不同的等式x+y=z, 其中x,y,z∈[1,9].
等式中只要有一个数字不一样 就是不一样的

思路:
计算下可以发现, 等式最多只有36个.
然后每个数字i的上界是17-i个 可以预先判掉答案一定是36的, 然后直接暴力搜索每个等式要不要就好了.
注意剪枝即可

 

  1 const int maxn = 20;
  2 int a[maxn];
  3 bool flag36;
  4 int ans;
  5 struct Equation
  6 {
  7     int x, y, z;
  8 } type[40];
  9 void init()
 10 {
 11     flag36 = true;
 12     ans = 0;
 13     for (int i = 1; i < 10; i++)
 14     {
 15         scanf("%d", a + i);
 16         if (a[i] < 17 - i) 
 17         {
 18             flag36 = false;
 19         }
 20     }
 21 }
 22 
 23 bool can(int t)
 24 {
 25     bool flag1 = false, flag2 = false, flag3 = false;
 26     bool ret = true;
 27     if (a[type[t].x] > 0) 
 28     {
 29         a[type[t].x]--;
 30         flag1 = true;
 31     }
 32     else ret = false;
 33     
 34     if (ret && a[type[t].y] > 0)
 35     {
 36         a[type[t].y]--;
 37         flag2 = true;
 38     }
 39     else ret = false;
 40 
 41     if (ret && a[type[t].z] > 0)
 42     {
 43         a[type[t].z]--;
 44         flag3 = true;
 45     }
 46     else ret = false;
 47 
 48     a[type[t].x] += flag1;
 49     a[type[t].y] += flag2;
 50     a[type[t].z] += flag3;
 51 
 52     return ret;
 53 }
 54 
 55 void dfs(int t, int cnt) // 判断第t中,已经凑出了cnt个
 56 {
 57     if (36 - t + cnt <= ans || t == 36) return;
 58     if (can(t))
 59     {
 60         a[type[t].x]--;    
 61         a[type[t].y]--;
 62         a[type[t].z]--;
 63         ans = max(ans, cnt + 1);
 64         dfs(t + 1, cnt + 1);
 65         a[type[t].x]++;
 66         a[type[t].y]++;
 67         a[type[t].z]++;
 68     }
 69     dfs(t + 1, cnt);
 70 }
 71 
 72 void solve()
 73 {
 74     if (flag36) 
 75     {
 76         printf("36\n");
 77         return;
 78     }
 79     dfs(0, 0);
 80     printf("%d\n", ans);
 81 }
 82 
 83 int main()
 84 {
 85     int idx = 0;
 86     for (int i = 1; i < 9; i++)
 87     {
 88         for (int j = 1; i + j < 10; j++)
 89         {
 90             type[idx++] = (Equation){i, j, i + j};
 91         }
 92     }
 93 
 94     int T, kase = 0;
 95     scanf("%d", &T);
 96     while (T--)
 97     {
 98         printf("Case #%d: ", ++kase);
 99         init();
100         solve();
101     }
102     return 0;
103 }

 

posted @ 2016-11-06 22:09  llysrv  阅读(146)  评论(0编辑  收藏  举报