HDU 4472 Count DP题

解题报告:题目大意,给你n个球,要将这n个球从下到上按层次排列,要求同一个层次的的每一个分支的数量都必须相等,问有多少种排列的方法。

此题的一个DP题,假设现在有n个球,要将这n个球排列好,我们就必须将n个球的问题转化成小于n个球的子问题 ,我们可以很明显地观察到,对于每一种排列 的方法,它的最上面的那一层总是只有一个球,所以我们就可以这样出发,将这n个球先减掉一个球,还剩下n-1个球,然后就是下一层怎么排列 的问题了。由于现在还剩下n-1个球,那么我们现在要想的就是把这n-1个球应该怎么排列,很显然,我们可以在第二层只放一个球,也可以放两个球,3个,四个、、、、n-1,判断下面一层放i个球到底是否可行的方法就是判断这n-1个球能否被平均分成i份,因为当第二层放了i个球之后,每个球的下一层要放同样多的球,所以要求就是能将这n-1个球平均分成i份就可以了。

 1 #include<cstdio>
 2 #include<cstring>
 3 const char feng[50][10]={"","DONG","NAN","XI","BEI","ZHONG","FA","BAI"};
 4 const char hua[50][3]={"T","S","W"};
 5 int mj[40],majiang[14];
 6 int judge(char *p) {
 7     if(p[0]>='0'&&p[0]<='9') {
 8         if(p[1]=='T')
 9         return (p[0]-'0'-1);
10         else if(p[1]=='S')
11         return (8+p[0]-'0');
12         else return (17+p[0]-'0');
13     }
14     else {
15         for(int i=1;i<=7;++i)
16         if(!strcmp(feng[i],p))
17         return (26+i);
18     }
19 }
20 bool find() {
21     for(int i=0;i<34;++i) {
22         if( mj[i] == 0 )
23         continue;
24         if(mj[i]>=3) {
25             mj[i]-=3;
26             i=0;
27             continue;
28         }
29         else if(i%9<=6 && i <= 24 &&mj[i]>=1&&mj[i+1]>=1&&mj[i+2]>=1) {
30             mj[i]--;
31             mj[i+1]--;
32             mj[i+2]--;
33             i=0;
34             continue;
35         }
36         else return false;
37     }
38     return true;
39 }
40 bool check(int d) {
41     for(int i=0;i<34;++i) {
42         memset(mj,0,sizeof(mj));
43         for(int j=0;j<13;++j)
44         mj[majiang[j]]++;
45         if(mj[d]>=4)
46         continue;
47         mj[d]++;
48         if(mj[i]>=2) {
49             mj[i]-=2;
50             if(find()) return true;
51         }
52     }
53     return false;
54 }
55 int main() {
56     char str[10];
57     int Case=1; 
58     while(scanf("%s",str)&&str[0]!='0') {
59         majiang[0]=judge(str);
60         int flag=0;
61         printf("Case %d:",Case++);
62         for(int i = 0; i<12;++i) {
63             scanf("%s",str);
64             majiang[i+1]=judge(str);
65         }
66         for(int i=0;i<34;++i) {
67             if(check(i)) {
68                 flag=1;
69                 if(i>=0&&i<=26)
70                 printf(" %d%s",(i%9+1),hua[i/9]);
71                 else printf(" %s",feng[i-26]);
72             }
73         }
74         if(!flag)
75         printf(" Not ready");
76         printf("\n");
77     }
78     return 0;
79 }
View Code

 

转载于:https://www.cnblogs.com/xiaxiaosheng/p/3192603.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值