zoukankan      html  css  js  c++  java
  • UVALive 6529

    题意:

      给你一个串数字,可以按任意顺序排列,求有几种排列可以使他们组成的数字可以被11整除。

    思路:

      和前几天那个被9整除的思想类似,1%11=1,10%11=10,100%11=1,1000%11=10.....容易观察出,设奇数位的和为x,偶数位的和为y,则(x+10y)%11的值为0就可以了--> (x-y+11y)%11=0 --> (x-y)%11=0。

      然后就可以dp做了dp[i][j][k]分别表示,当前在放数字i-1,之前已经放了j个数字,现在(x-y)%11的值为k。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 #define MOD 1000000007
     6 typedef long long LL;
     7 LL C[110][110],num[15];
     8 LL dp[11][101][11];
     9 
    10 char ch[110];
    11 void init(){
    12     C[0][0]=C[1][0]=C[1][1]=1;
    13     for(int i=2;i<=100;i++){
    14         for(int j=0;j<=i;j++){
    15             if(j==0) C[i][j] = 1;
    16             else C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
    17         }
    18     }
    19 }
    20 
    21 LL cal(int len){
    22     memset(dp,0,sizeof(dp));
    23     dp[0][0][0]=1;
    24     int sum = 0; int need = (len+1)>>1;
    25     for(int i=1;i<=10;i++){
    26         for(int j=0;j<=sum && j<=need;j++){
    27             for(int k=0;k<=num[i-1] && (j+k)<=need;k++){
    28                 int change = (2*k-num[i-1])*(i-1)%11;
    29                 if(change<0) change+=11;
    30                 for(int l=0;l<11;l++){
    31                     int next = (change + l)%11;
    32                     dp[i][j+k][next] = (dp[i][j+k][next] + dp[i-1][j][l] * C[need-j][k] %MOD* C[len-need-sum+j][num[i-1]-k] %MOD)%MOD;
    33                 }
    34             }
    35         }
    36         sum+=num[i-1];
    37     }
    38     return dp[10][need][0];
    39 }
    40 
    41 void solve(){
    42     memset(num,0,sizeof(num));
    43     for(int i=0;ch[i];i++){
    44         num[ch[i]-'0']++;
    45     }
    46     int len=strlen(ch);
    47     LL ans = cal(len);
    48     if(num[0]){
    49         num[0]--;
    50         LL ans2 = cal(len-1);
    51         ans=((ans-ans2)%MOD+MOD)%MOD;
    52     }
    53     cout<<ans<<endl;
    54 }
    55 
    56 int main(){
    57     init();
    58     while(scanf("%s",ch)!=EOF){
    59         solve();
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    今天面试一些程序员(新,老)手的体会
    UVA 10635 Prince and Princess
    poj 2240 Arbitrage
    poj 2253 Frogger
    poj 2485 Highways
    UVA 11258 String Partition
    UVA 11151 Longest Palindrome
    poj 1125 Stockbroker Grapevine
    poj 1789 Truck History
    poj 3259 Wormholes
  • 原文地址:https://www.cnblogs.com/SolarWings/p/3452690.html
Copyright © 2011-2022 走看看