HDU 5937 Equation 【DFS+剪枝】 (2016年中国大学生程序设计竞赛(杭州))
Equation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 92 Accepted Submission(s): 24
Problem DescriptionLittle Ruins is a studious boy, recently he learned addition operation! He was rewarded some number bricks of 1 to 9 and infinity bricks of addition mark '+' and equal mark '='.
Now little Ruins is puzzled by those bricks because he wants to put those bricks into as many different addition equations form x+y=z as possible. Each brick can be used at most once and x, y, z are one digit integer.
As Ruins is a beginer of addition operation, x, y and z will be single digit number.
Two addition equations are different if any number of x, y and z is different.
Please help little Ruins to calculate the maximum number of different addition equations.
InputFirst line contains an integer T, which indicates the number of test cases.
Every test case contains one line with nine integers, the ith integer indicates the number of bricks of i.
Limits
1≤T≤30
0≤bricks number of each type≤100
OutputFor every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result.
Sample Input3 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 0 3 3 0 3 0 0 0 0
Sample OutputCase #1: 2 Case #2: 6 Case #3: 2
Source
Recommend
Statistic | Submit | Discuss | Note
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5937
题目大意:
给1~9 9个数字,每个数字有Xi个,问总共能凑成多少个不同的等式A+B=C(A B C均为1位,1+2=3和2+1=3视为不同等式)
题目思路:
【DFS+剪枝】
这题本来想成网络流,建图建不出来最后只能靠爆搜+剪枝过了【我太弱了,第一名15ms过的。我234ms。可能有正解吧】
首先列出等式总共就36种,每种数字最多需要17-i个,然后我就这样爆搜+剪枝T的死死的。
后来经学长点拨说可以缩到20(视为有序,1+2=3和2+1=3视为同一种,乘上1或2)
然后我又调整了下搜索的顺序,然后就。。过了。
【程序里a是等式,b是三个数,c是能够用几次,d是前i个最多能组成多少等式】
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<set> 12 #include<bitset> 13 #include<memory.h> 14 #include<time.h> 15 #include<stdio.h> 16 #include<stdlib.h> 17 #include<string.h> 18 //#include<stdbool.h> 19 #include<math.h> 20 #pragma comment(linker,"/STACK:1024000000,1024000000") 21 #define min(a,b) ((a)<(b)?(a):(b)) 22 #define max(a,b) ((a)>(b)?(a):(b)) 23 #define abs(a) ((a)>0?(a):(-(a))) 24 #define lowbit(a) (a&(-a)) 25 #define sqr(a) ((a)*(a)) 26 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 27 #define mem(a,b) memset(a,b,sizeof(a)) 28 #define eps (1e-8) 29 #define J 10000 30 #define mod 1000000007 31 #define MAX 0x7f7f7f7f 32 #define PI 3.14159265358979323 33 #define N 24 34 #define M 1004 35 using namespace std; 36 typedef long long LL; 37 double anss; 38 LL aans; 39 int cas,cass; 40 int n,m,lll,ans; 41 int num[10]; 42 int a[N]={ 43 112, 44 123, 45 134,224, 46 145,235, 47 156,246,336, 48 167,257,347, 49 178,268,358,448, 50 189,279,369,459}; 51 int b[N][3]={ 52 {1,1,2}, 53 {1,2,3}, 54 {1,3,4},{2,2,4}, 55 {1,4,5},{2,3,5}, 56 {1,5,6},{2,4,6},{3,3,6}, 57 {1,6,7},{2,5,7},{3,4,7}, 58 {1,7,8},{2,6,8},{3,5,8},{4,4,8}, 59 {1,8,9},{2,7,9},{3,6,9},{4,5,9}}; 60 int c[N]={ 61 1, 62 2, 63 2,1, 64 2,2, 65 2,2,1, 66 2,2,2, 67 2,2,2,1, 68 2,2,2,2}; 69 int d[N]={ 70 1, 71 3, 72 5,6, 73 8,10, 74 12,14,15, 75 17,19,21, 76 23,25,27,28, 77 30,32,34,36}; 78 void dfs(int top,int le,int l) 79 { 80 if((ans-top)*3>=le)return; 81 if(ans-top>=d[l-1])return; 82 int i,x,y,z; 83 ans=max(ans,top); 84 for(i=l-1;i>=0;i--) 85 { 86 x=b[i][0],y=b[i][1],z=b[i][2]; 87 num[x]--,num[y]--,num[z]--; 88 if(num[x]>=0 && num[y]>=0 && num[z]>=0) 89 dfs(top+1,le-3,i); 90 if(c[i]>1) 91 { 92 num[x]--,num[y]--,num[z]--; 93 if(num[x]>=0 && num[y]>=0 && num[z]>=0) 94 dfs(top+2,le-6,i); 95 num[x]++,num[y]++,num[z]++; 96 } 97 num[x]++,num[y]++,num[z]++; 98 } 99 } 100 int main() 101 { 102 #ifndef ONLINE_JUDGE 103 freopen("1.txt","r",stdin); 104 // freopen("2.txt","w",stdout); 105 #endif 106 int i,j,k; 107 int x,y,z; 108 // init(); 109 // for(scanf("%d",&cass);cass;cass--) 110 for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 111 // while(~scanf("%s",s)) 112 // while(~scanf("%d%d",&n,&m)) 113 { 114 printf("Case #%d: ",cass); 115 z=0;ans=0; 116 for(i=1;i<10;i++) 117 { 118 scanf("%d",&num[i]); 119 num[i]=min(num[i],17-i); 120 z+=num[i]; 121 } 122 if(num[9])i=20; 123 else if(num[8])i=16; 124 else if(num[7])i=12; 125 else if(num[6])i=9; 126 else if(num[5])i=6; 127 else if(num[4])i=4; 128 else if(num[3])i=2; 129 else if(num[2])i=1; 130 dfs(0,z,i); 131 printf("%d\n",ans); 132 } 133 return 0; 134 } 135 /* 136 // 137 138 // 139 */