码迷,mamicode.com
首页 > 其他好文 > 详细

第二周 9.7---9.13

时间:2015-09-07 14:20:43      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:

---------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 }
View Code

 

新的一周----加油--------------------------

 

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 }
View Code

 

第二周 9.7---9.13

标签:

原文地址:http://www.cnblogs.com/wuyuewoniu/p/4788637.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!