---------9.7
cf 575 h
http://codeforces.com/problemset/problem/575/H
题意不懂怎么描述诶,大意就是
先有一颗满二叉树,然后从根到叶子的路上有n条边染成红色,n条边染成蓝色,问满足这样条件的树有多少个节点
想到一点点,就是每次扩展下一层的时候,用本来应该满足满二叉树的节点数减去不合法的节点数---
可是不懂算这里------
本来按照一颗正常的二叉树
每扩展一层,节点数乘以2
但是因为有n的限制
就不会增加那么多个的节点
在前n层,是没有限制的,红色蓝色任意选
但是到第n+1层,因为肯定有两条路是已经填完红色,蓝色的
所以 它增加的节点数 为 ( C(n+1,n) - C(n,n) ) *2
然后假设现在走到深度为 K + 1
它比上一层增加的节点数 为 (C(K+1,n) - C(K,n))*2
再一层层的算
----------------话说不懂组合数取模,先抄了个lucas,T了
后来----抄了一个预处理的---------还是不懂这样算组合数---------------
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long ll; 8 const int MAXN = 2000010; 9 const ll mod = 1e9 + 7; 10 11 int N; 12 ll fac[MAXN + 10],afac[MAXN + 10]; 13 14 ll Q_pow(ll x,ll y){ 15 ll res = 1; 16 x %= mod; 17 while(y){ 18 if(y & 1) res = res * x % mod; 19 x = x * x % mod; 20 y >>= 1; 21 } 22 return res; 23 } 24 25 void Pre(){ 26 fac[0] = 1; 27 for(int i = 1; i <= MAXN; ++i) fac[i] = fac[i - 1] * (ll)i % mod; 28 afac[MAXN] = Q_pow(fac[MAXN],mod - 2); 29 for(int i = MAXN; i >= 1; --i) afac[i - 1] = afac[i] * i % mod; 30 } 31 32 ll C(ll n,ll m){ 33 if(m > n) return 0; 34 return fac[n] * afac[n - m] % mod * afac[m] % mod; 35 } 36 37 int main(){ 38 Pre(); 39 scanf("%d",&N); 40 ll ans = Q_pow(2,N+1)-1; 41 ll cur = Q_pow(2,N); 42 ll tmp = cur; 43 for(int i = N+1;i <= 2*N;i++){ 44 ll shao = 2LL*((C(i-1,N) - C(i-2,N) + mod) % mod) %mod; 45 // printf("shao = %I64d\n",shao); 46 tmp = (tmp-shao + mod)%mod; 47 cur = cur + tmp; 48 ans = (ans + cur) %mod; 49 tmp = 2LL*tmp%mod; 50 } 51 printf("%I64d\n",ans); 52 return 0; 53 }
新的一周----加油--------------------------
cf 2B
http://codeforces.com/problemset/problem/2/B
这题目的编号 >_<
不会做------------
先想的是 dp[i][j]表示走到第i行,第j列的0最少有多少个
可是转移不出来
后来,题解是这样做的
因为答案所在的路径要不然是含有2的个数最少的,要不然是含有5的个数最少的
画几个例子就懂了---
然后就按照2的个数少dp一次,按照5的个数少dp一次
不过要注意给出的矩阵中本身含有0的情况
如果矩阵中含有0,就要用1和 dp2 ,dp5的答案去比较,1更小的话,直接构造出一条走0的路线
还是不懂路径打印----在cf上翻了一份------
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int INF = (1<<30)-1; 8 const int maxn = 1005; 9 int f[maxn][maxn][2],g[maxn][maxn][2]; 10 int n,x,pos; 11 12 void print(int x,int y){ 13 if(x == 1 && y == 1) return; 14 if(g[x][y][pos]) print(x-1,y),printf("D"); 15 else print(x,y-1),printf("R"); 16 } 17 18 int main(){ 19 scanf("%d",&n); 20 memset(f,0,sizeof(f)); 21 memset(g,0,sizeof(g)); 22 23 for(int i = 2;i <= n;i++) 24 f[i][0][0] = f[i][0][1] = f[0][i][1] = f[0][i][0] = INF; 25 26 for(int i = 1;i <= n;i++){ 27 for(int j = 1;j <= n;j++){ 28 int k; 29 scanf("%d",&k); 30 if(k == 0) x = i; 31 while(k){ 32 if(k%2 != 0) break; 33 k = k/2; 34 f[i][j][0]++; 35 } 36 while(k){ 37 if(k%5 != 0) break; 38 k = k/5; 39 f[i][j][1]++; 40 } 41 for(int k = 0;k < 2;k++){ 42 if(f[i-1][j][k] < f[i][j-1][k]) { 43 f[i][j][k] += f[i-1][j][k]; 44 g[i][j][k] = 1;//D 45 } 46 else{ 47 f[i][j][k] += f[i][j-1][k]; 48 g[i][j][k] = 0; 49 } 50 } 51 } 52 } 53 54 // for(int i = 1;i <= n;i++){ 55 // for(int j = 1;j <= n;j++){ 56 // for(int k = 1;k < 2;k++) 57 // printf("f[%d][%d][%d] = %d g[%d][%d][%d] = %d\n",i,j,k,f[i][j][k],i,j,k,g[i][j][k]); 58 // } 59 // } 60 61 if(f[n][n][0] < f[n][n][1]) pos = 0; 62 else pos = 1; 63 64 int ans = min(f[n][n][0],f[n][n][1]); 65 if(x && (ans > 1)){ 66 puts("1"); 67 for(int i = 2;i <= x;i++) printf("D"); 68 for(int i = 2;i <= n;i++) printf("R"); 69 for(int i = x+1;i <= n;i++) printf("D"); 70 } 71 else{ 72 printf("%d\n",ans); 73 print(n,n); 74 } 75 76 return 0; 77 }