zoukankan      html  css  js  c++  java
  • POJ 2711 Regular Words(DP + 高精度)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1711

    题目大意:给定一个正整数n,产生一个3*n位长的串,要求这个串中(1)A、B、C的数目都是n;(2)这个串的任意一个前缀,也就是从开始往后任意一段连续序列中字符的个数A>=B>=C。求满足条件的数目。

    Sample Input

    2
    
    3
    
    

    Sample Output

    5
    
    42

    分析:令dp[i][j][k]  表示从第一个字符开始,长度为i+j+k的串,A的个数为 i ,B的个数为 j ,C的个数为 k 的字符串的个数。  

      则如果i>=j>=k  则可以根据最后一个字符是A, B还是C,分三类计数,假设是最后一位是A,由于题目的要求是前缀 ,所以前面的放法数恰好是dp[i-1][j][k]

      另外两种情况同理,加的时候注意下标小于零就不要了,答案为dp[n][n][n]

      后来发现是高精度,需要再加一维dp[i][j][k][p],最后一维是该数字的大数表示。

      这样如果dp数组用int类型表示,会超内存。后来改用short类型,内存36000险过,用char类型也是可以过的。short型理论上用输出%hd的,不过%d也可以。

    代码如下:

     1 # include<iostream>
     2 # include<cstdio>
     3 # include<cstring>
     4 using namespace std;
     5 
     6 short dp[61][61][61][81];
     7 void init()
     8 {
     9     short i,j,k,p,temp;
    10     memset(dp,0,sizeof(dp));
    11     dp[0][0][0][0] = 1;
    12     for(i=0; i<=60; i++)
    13         for(j=i; j<=60; j++)
    14             for(k=j; k<=60; k++)
    15             {
    16                 if(i>0)     //dp[i][j][k] += dp[i-1][j][k];
    17                 {
    18                     temp = 0;
    19                     for(p=0; p<=80; p++)
    20                     {
    21                         dp[i][j][k][p] += dp[i-1][j][k][p] + temp;
    22                         if(dp[i][j][k][p]>9)
    23                         {
    24                             temp = 1;
    25                             dp[i][j][k][p] -= 10;
    26                         }
    27                         else
    28                             temp = 0;
    29                     }
    30                 }
    31                 if(j>0) //dp[i][j][k] += dp[i][j-1][k];
    32                 {
    33                     temp = 0;
    34                     for(p=0; p<=80; p++)
    35                     {
    36                         dp[i][j][k][p] += dp[i][j-1][k][p] + temp;
    37                         if(dp[i][j][k][p]>9)
    38                         {
    39                             temp = 1;
    40                             dp[i][j][k][p] -= 10;
    41                         }
    42                         else
    43                             temp = 0;
    44                     }
    45                 }
    46                 if(k>0) //dp[i][j][k] += dp[i][j][k-1];
    47                 {
    48                     temp = 0;
    49                     for(p=0; p<=80; p++)
    50                     {
    51                         dp[i][j][k][p] += dp[i][j][k-1][p] + temp;
    52                         if(dp[i][j][k][p]>9)
    53                         {
    54                             temp = 1;
    55                             dp[i][j][k][p] -= 10;
    56                         }
    57                         else
    58                             temp = 0;
    59                     }
    60                 }
    61             }
    62 }
    63 
    64 int main()
    65 {
    66     init();
    67     int n;
    68     while(scanf("%d",&n)!=EOF)
    69     {
    70         int i;
    71         for(i=80; i>=0; i--)
    72             if(dp[n][n][n][i] != 0) break;  
    73         for(; i>=0; i--)    //输出高精度数
    74             printf("%d",dp[n][n][n][i]);
    75         printf("
    
    ");
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    APS系统如何落地?用户实际痛点解析!
    供应链如何优化?高级排程系统为其运算
    不懂APS系统?十个问答让你对APS瞬间明明白白
    智能制造主战场在哪?数字化车间建设尤为重要
    中国制造转型的关键在哪里?智能制造点亮发展明灯
    你家的APS系统有这些功能吗?排程系统功能盘点
    微软正开发Office Reader和Office Lens
    C#的3DES加密解密算法
    如何在SharePoint2010中创建自定义电子邮件警报处理程序
    规划SharePoint2010的管理员密码更改
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3309090.html
Copyright © 2011-2022 走看看