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+;
const int N = ;
const int M = ; LL cnt[M] , dp[M][N][M] , C[N][N];
string s; void Init() {
C[][] = ;
for( int i = ; i < N ; ++i ){
for( int j = ; j <= i ; ++j ){
C[i][j]=(j==)?:(C[i-][j]+C[i-][j-])%mod ;
}
}
}
void Run() {
memset( cnt , ,sizeof cnt ) ;
memset( dp , ,sizeof dp ) ;
int n = s.size() , n2 = n / , n1 = n - n2 ;
for( int i = ; i < n ; ++i ) cnt[ -(s[i]-'') ]++ ;
dp[][][] = ; LL sum = ;
for( int i = ; i < ; ++i ) { // digit
for( int j = ; j <= n1 ; ++j ) { // odd used
for( int k = ; k < ; ++k ) { // remainder
if( !dp[i][j][k] || j > sum ) continue ;
int j1 = j , j2 = sum - j;
for( int z = ; 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&) && i== ) tmp = tmp * C[j1+z1-][z1] % mod ;
else tmp = tmp * C[j1+z1][z1] % mod ;
if(!(n&) && i== ) tmp = tmp * C[j2+z2-][z2] % mod ;
else tmp = tmp * C[j2+z2][z2] % mod;
int _i = i + , _j = j1 + z1 , _k = ( k + z1*(-i)-z2*(-i)+*)%;
dp[_i][_j][_k] = ( dp[_i][_j][_k] + tmp ) % mod ;
}
}
}
sum += cnt[i];
}
cout << dp[][n1][] << endl ;
} int main(){
Init(); while( cin >> s ) Run();
}

最新文章

  1. java连接oracle范例
  2. Gradle用户指南(中文版)
  3. 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化
  4. Codeforces Round #286 Div.1 A Mr. Kitayuta, the Treasure Hunter --DP
  5. android studio-创建第一个项目
  6. Kubuntu 使用YaH3C进行中大校园网认证
  7. 在Dll中使用 TFDQuery 的 LoadFromStream 方法注意问题
  8. js unix时间戳转换
  9. C# 判断一字符串是否为合法数字(正则表达式)
  10. kindeditor 上传图片 显示绝对 路径
  11. contiki makefile框架分析 &lt; contiki学习之一 &gt;
  12. python 自动化之路 day 01.1 数据类型
  13. 3行3列表格 table实现,div+css实现
  14. Adapter 模式
  15. QT5控件-QPushButton和QFocusFrame(按钮和焦点框)
  16. NoSql的产生
  17. Spring Boot快速建立HelloWorld项目
  18. React-Native 学习笔记-Android开发平台-开发环境搭建
  19. Android手机ROM刷机简介
  20. vue 在.vue文件里监听路由

热门文章

  1. python3使用print打印带颜色的字符串
  2. IBM IMM默认ID
  3. 【LeetCode】线段树 segment-tree(共9题)+ 树状数组 binary-indexed-tree(共5题)
  4. Python3.5-20190530-unittest模块
  5. bzoj5049 [Lydsy1709月赛]导航系统 双向bfs
  6. phpstrom 安装
  7. python基础面试题总结
  8. BZOJ 2694: Lcm 莫比乌斯反演 + 积性函数 + 线性筛 + 卡常
  9. FS,FT,DFS,DTFT,DFT,FFT的联系和区别 数字信号处理
  10. js获取URL地址的参数