• 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("
    ");
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    双指针
    git .gitignore文件修改后不生效
    Vue路由跳转携带固定参数
    GitLab 安装说明
    安装 PostgreSQL
    职场软素质&算法工程师的硬素质卓越的职场人需要的42种能力
    内存泄漏排查
    Oracle基本操作(登陆、用户、表空间、exp/imp、权限)
    oracle删除用户、表空间及数据⽂件⽅法
    oracle检查存储过程出错原因
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3192603.html
Copyright © 2020-2023  润新知