zoukankan      html  css  js  c++  java
  • UESTC_秋实大哥掰手指 2015 UESTC Training for Dynamic Programming<Problem B>

    B - 秋实大哥掰手指

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 2048/1024KB (Java/Others)
     

    秋实大哥发现数据结构专题出到了N题,但是他一时算不出来已经有了几道题,他就萌萌地掰手指数。 这个时候他发现,虽然人们根据手指数创造了十进制数,但是两只手同时能表达的数是0-10一共十一个数字。 这样,他觉得如果用手指表现十进制数,同一个十进制数就会有很多种不同的表现方法。 比如,110这样一个十进制数,就有110(1*100+1*10+0*1),AA(10*10+10*1 )和10A(1*100+0*10+10*1)三种表示方法(A表示伸出十根手指)。

    title

    title

    title

    现在给你一些十进制数,聪明的你能不能计算出按照秋实大哥的方法,每个数能有多少种表现方式(方案数对1000000007取模)。

    Input

    只有一组数据,第一行一个数字n,表示人赢给出的数字的长度。 第二行一个整数a(1<=a<=1e1000000),表示给出的十进制数。

    Output

    对于每组数据输出一个整数,表示输入的数人赢有多少种表示方法(结果可能很大,取模1000000007的余数)。

    Sample input and output

    Sample InputSample Output
    1 
    1
    1
    3
    110
    3
    6
    100100
    
    11

    Hint

    注意内存~~ 怎么处理课上会讲呀~~

    解题报告:

    根据题目条件,我们不难想到上一位最多只能缺 10 (即在上一位摆的数比规定数字少 1 ),那么我们可以设计这样的状态:

     F( i , 0 )  表示第 i 位为止,不缺 10 的方案数.

     F( i , 1 )  表示第 i 位为止,缺 10 的方案数.

    如何转移呢?

     我们先假设当前正在转移第 i 位,且第 i 位的数字为 Number.

     显然有

      f( i , 0 )  += f( i – 1 , 0 ) ; //上一位就不缺,这一位也不缺,正常摆.

      If (Number == 0)

    f( i , 0 )  += f( i – 1 , 1 ) ;  //上一位缺了 10 ,这位恰好是 0 ,补上.

    f( i , 1 )  += f( i – 1 , 1 ) ;  //上一直缺了 10 ,这次不妨摆 9 ,转移到下一位依然缺 10

      else if (Number == 1)

    f( i , 1 )  += f( i – 1 , 1 )  //这一位需要 11 ,摆 10 ,转移到下一位依然缺 10

    f( i , 1 )  += f( i – 1 , 0 )  //上一位不缺,这一位摆的数少 1 ,转移到下一位缺 10

      else

    f( i , 1 )  += f( i – 1 , 0 )  //上一位不缺,这一位摆的数少 1 ,转移到下一位缺 10

     

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    typedef long long ll;
    ll mod = 1000000007;
    ll f[2][2];
    /*
    0 到上次为止,不缺
    1 到上次为止,缺10
    */
    int cur = 0;
    void init_()
    {
       int i;
       for(i = 0 ; i <= 1 ; ++ i)
          f[cur][i] = 0;
    }
    
    int main(int argc,char *argv[])
    {
      int n,i,j,c,k;
      scanf("%d",&n);
      char ch;
      while(1)
       {
             ch = getchar();
             if (ch == '
    ')
              break;
       }
      memset(f,0,sizeof(f));
      //
        ch = getchar();
        int num = ch - '0';
        f[cur][0]  = 1;
        if (num != 0)
         f[cur][1]  = 1;
      //
      for(i = 1 ; i < n ; ++ i)
       {
             cur ^= 1;
             init_();
             ch = getchar();
             int num = ch - '0';
             f[cur][0] = (f[cur][0] % mod+ f[cur^1][0] % mod ) % mod;
             if (num == 0)
              {
                 f[cur][0] = (f[cur][0] % mod+ f[cur^1][1] % mod) % mod;
                 f[cur][1] = (f[cur][1] % mod+ f[cur^1][1] % mod) % mod;
           }
          else if(num == 1)
           {
                 f[cur][1] = (f[cur][1] % mod +  f[cur^1][1] % mod ) % mod;
                 f[cur][1] = (f[cur][1] % mod +  f[cur^1][0] % mod) % mod;
           }
          else
           {
                 f[cur][1] = (f[cur][1] % mod +  f[cur^1][0] % mod ) % mod;
           }
       }
      printf("%lld
    ",f[cur][0] % mod);
      return 0;
    }
    No Pain , No Gain.
  • 相关阅读:
    你了解RTOS吗?
    [转] git rebase 详解
    MinGW vs MinGW-W64及其它
    【转】Video Rendering with 8-Bit YUV Formats
    Ubuntu假死
    渐进增强和优雅降级的区别
    JavaScript 插件的学习
    菜单的制作
    生活
    小组学习情况
  • 原文地址:https://www.cnblogs.com/Xiper/p/4539605.html
Copyright © 2011-2022 走看看