zoukankan      html  css  js  c++  java
  • UVA 12672 Eleven(DP)

    12672 - Eleven

    Time limit: 5.000 seconds

    In this problem, we refer to the digits of a positive integer as the sequence of digits required to write
    it in base 10 without leading zeros. For instance, the digits of N = 2090 are of course 2, 0, 9 and 0.
    Let N be a positive integer. We call a positive integer M an eleven-multiple-anagram of N if and
    only if (1) the digits of M are a permutation of the digits of N, and (2) M is a multiple of 11. You are
    required to write a program that given N, calculates the number of its eleven-multiple-anagrams.
    As an example, consider again N = 2090. The values that meet the first condition above are 2009,
    2090, 2900, 9002, 9020 and 9200. Among those, only 2090 and 9020 satisfy the second condition, so
    the answer for N = 2090 is 2.


    Input
    The input file contains several test cases, each of them as described below.
    A single line that contains an integer N (1 ≤ N ≤ 10^100).


    Output
    For each test case, output a line with an integer representing the number of eleven-multiple-anagrams
    of N . Because this number can be very large, you are required to output the remainder of dividing it
    by 109 + 7.


    Sample Input
    2090
    16510
    201400000000000000000000000000


    Sample Output
    2
    12
    0

    一条很好的DP题。

    问一个数重排后(不包括前序0) , 有多少个数能够被整除11。

    对于11的倍数,可以发现一个规律就是:

    ( 奇数位数字的总和 - 偶数为数字的总和  )% 11 == 0的数能够被11整除

    因为作为11的倍数,都符合:

      77000                          85481是可以被11整除的。             

        7700                          因为它各个相邻位都有一个相等的性质。

          770                          对于奇数位要进位的话,相当于少加了10(即-10) , 同时偶数为多了1(即-1) ,还是符合被11整除

            11                          偶数为亦然 , 偶数为进位, 相当于少减10 ,(即+10) , 同时奇数位多了1(即+1)。

    ------------

       85481                              

    那么,设一个 dp[i][j][k] 表示用了i位(0~9)数字,奇数位有j个数,余数是k的组合成的数有多少个。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int mod = 1e9+7;
    const int N = 205 ;
    const int M = 11 ;
    
    LL cnt[M] , dp[M][N][M] , C[N][N];
    string s;
    
    void Init() {
        C[0][0] = 1 ;
        for( int i = 1 ; i < N ; ++i ){
            for( int j = 0 ; j <= i ; ++j ){
                C[i][j]=(j==0)?1:(C[i-1][j]+C[i-1][j-1])%mod ;
            }
        }
    }
    void Run() {
        memset( cnt , 0 ,sizeof cnt ) ;
        memset( dp , 0 ,sizeof dp ) ;
        int n = s.size() , n2 = n / 2 , n1 = n - n2 ;
        for( int i = 0 ; i < n ; ++i ) cnt[ 9-(s[i]-'0') ]++ ;
        dp[0][0][0] = 1 ; LL sum = 0 ;
        for( int i = 0 ; i < 10 ; ++i ) {                // digit
            for( int j = 0 ; j <= n1 ; ++j ) {           // odd used
                for( int k = 0 ; k < 11 ; ++k ) {        // remainder
                    if( !dp[i][j][k] || j > sum ) continue ;
                    int j1 = j , j2 = sum - j;
                    for( int z = 0 ; z <= cnt[i] ; ++z ){
                        int z1 = z , z2 = cnt[i] - z ;
                        if( j1 + z1 > n1 || j2 + z2 > n2 ) continue ;
                        LL tmp = dp[i][j][k];
                        if( (n&1) && i==9 ) tmp = tmp * C[j1+z1-1][z1] % mod ;
                        else tmp = tmp * C[j1+z1][z1] % mod ;
                        if(!(n&1) && i==9 ) tmp = tmp * C[j2+z2-1][z2] % mod ;
                        else tmp = tmp * C[j2+z2][z2] % mod;
                        int _i = i + 1 , _j = j1 + z1 , _k = ( k + z1*(9-i)-z2*(9-i)+11*10000)%11;
                        dp[_i][_j][_k] = ( dp[_i][_j][_k] + tmp ) % mod ;
                    }
                }
            }
            sum += cnt[i];
        }
        cout << dp[10][n1][0] << endl ;
    }
    
    int main(){
        Init(); while( cin >> s ) Run();
    }
    View Code
    only strive for your goal , can you make your dream come true ?
  • 相关阅读:
    linux学习方法之一
    HDU 1556 Color the ball
    Object-c学习之路十(NSNumber&NSValue)
    蜂鸣器驱动方式源程序--有源无源通用
    Wordpress更换主题之后出错
    mybatis_Generator配置
    Logistic Regression
    求两个字符串的最大公共字串
    数据结构排序系列详解之二 希尔排序
    《mysql必知必会》学习_第五章
  • 原文地址:https://www.cnblogs.com/hlmark/p/4159579.html
Copyright © 2011-2022 走看看