zoukankan      html  css  js  c++  java
  • NOI前做题记录

      快NOI了还啥都不会,蛤蛤要梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒。

      为什么我的键盘还不到还不到还不到还不到还不到还不到还不到还不到。

      不一定每道题都写,不一定写的很清楚,各位无聊的时候可以看着玩玩,咕咕咕。

    白金元首与莫斯科

      比较巧妙的题目,顺着倒着分别轮廓线dp,在障碍处拼起来。因为空格子可能非常麻烦,所以将其视为1*1的小方格,这样就只有目前考虑的轮廓线可能有空了。当两个轮廓拼起来时,所有空格就必须填上,所以轮廓线必须相应对上,才能用竖直方格填满。

      
      1 # include <cstdio>
      2 # include <iostream>
      3 # define R register int
      4 
      5 using namespace std;
      6 
      7 const int N=20;
      8 const int Q=(1<<17)+100;
      9 const int mod=1000000007;
     10 int n,m,q,a[N][N],bit[N];
     11 int f[N][N][Q],g[N][N][Q];
     12 
     13 void add (int &a,int b)
     14 {
     15     a+=b;
     16     if(a>=mod) a-=mod;
     17 }
     18 
     19 int ask (int i,int j)
     20 {
     21     int ans=0;
     22     for (R k=0;k<=q;++k)
     23         if(k&bit[j])
     24         add(ans,1LL*f[i][j-1][k]*g[i][j+1][k]%mod);
     25     return ans;
     26 }
     27 
     28 int main()
     29 {
     30     scanf("%d%d",&n,&m);
     31     for (R i=1;i<=m;++i) bit[i]=1<<(i-1);
     32     for (R i=1;i<=n;++i)
     33         for (R j=1;j<=m;++j)
     34             scanf("%d",&a[i][j]);
     35     q=(1<<m)-1;
     36     f[1][0][q]=1;
     37     for (R i=1;i<=n;++i)
     38         for (R j=1;j<=m;++j)
     39         {
     40             for (R k=0;k<=q;++k)
     41             {
     42                 int t=f[i][j-1][k];
     43                 if(t==0) continue;
     44                 if((k&bit[j])==0)
     45                 {
     46                     if(a[i][j]) continue; //上面那个一定不能空,否则永远填不上
     47                     add(f[i][j][ k|bit[j] ],t);
     48                     continue;
     49                 }
     50                 if(a[i][j]) add(f[i][j][k],t);
     51                 else
     52                 {
     53                     add(f[i][j][k],t);
     54                     add(f[i][j][k^bit[j]],t);
     55                     if(j!=1&&(k&bit[j-1])==0) add(f[i][j][ k|bit[j-1] ],t);
     56                 }
     57             }
     58             if(j==m)
     59             {
     60                 for (R k=0;k<=q;++k) 
     61                     f[i+1][0][k]=f[i][j][k];
     62             }
     63         }
     64     g[n][m+1][q]=1;
     65     for (R i=n;i>=1;--i)
     66         for (R j=m;j>=1;--j)
     67         {
     68             for (R k=0;k<=q;++k)
     69             {
     70                 int t=g[i][j+1][k];
     71                 if(!t) continue;
     72                 if((k&bit[j])==0)
     73                 {
     74                     if(a[i][j]) continue;
     75                     add(g[i][j][ k|bit[j] ],t);
     76                     continue;
     77                 }
     78                 if(a[i][j]) add(g[i][j][k],t);
     79                 else
     80                 {
     81                     add(g[i][j][k],t);
     82                     add(g[i][j][k^bit[j]],t);   
     83                     if(j!=m&&(k&bit[j+1])==0)
     84                         add(g[i][j][k|bit[j+1]],t);
     85                 }
     86             }
     87             if(j==1)
     88             {
     89                 for (R k=0;k<=q;++k)
     90                     g[i-1][m+1][k]=g[i][j][k];
     91             }
     92         }
     93     for (R i=1;i<=n;++i)
     94     {
     95         for (R j=1;j<=m;++j)
     96         {
     97             if(a[i][j]) printf("0 ");
     98             else printf("%d ",ask(i,j));
     99         }
    100         printf("
    ");
    101     }
    102     return 0;
    103 }
    code

    喂鸽子

      min-max容斥,由于每只鸽子是平等的,不用枚举集合,只要枚举集合的大小就可以了。设 $g(i)$ 表示有i只鸽子的情况下,第一次有鸽子吃饱的期望时间,则 $ans=sum_{i=1}^n(-1)^{i+1}inom{n}{i}g(i)$;

      设 $P(n,x=i)$ 表示 $n$ 只鸽子在 $i$ 时刻第一次有某只吃饱的概率,则有:$g(n)=sum_{i=1}^{infin}i imes P(n,i)$,也可以转化为 $g(n)=sum_{i=1}^{infin} P(n,xgeq i)$。

      设 $f(i,j)$ 表示 $i$ 只鸽子,喂了 $j$ 个玉米,但是每只都没吃饱的概率。

    如何优雅地求和

      假装我们已经将f变成了一个下降幂多项式,即:$f(x)=sum_{i=0}^m f_ix^{underline{i}}$;

      那么$egin{align} ans&=sum_{i=0}^mf_isum_{k=0}^nk^{underline{i}}inom{n}{k}x^k(1-x)^{n-k}\ &=sum_{i=0}^mf_isum_{k=0}^nfrac{k!}{(k-i)!}frac{n!}{k!(n-k)!}x^k(1-x)^{n-k}\ &=sum_{i=0}^mf_isum_{k=0}^nfrac{n!}{(k-i)!(n-k)!}x^k(1-x)^{n-k}   \ &=sum_{i=0}^mf_in^{underline{i}}x^{i}sum_{k=0}^ninom{n-i}{k-i}x^{k-i}(1-x)^{n-k}\ &=sum_{i=0}^mf_in^{underline{i}}x^{i}(x+1-x)^{n-i}\&=sum_{i=0}^mf_in^{underline{i}}x^{i}end{align}$

      那么现在的问题就是怎么转化出下降幂多项式了。

    一个有意思的小技巧

      $\% 2$ 意义下的多项式的平方很好求,把每一项的指数都乘二就好啦,就是说 $f_ix^i->f_ix^{2i}$;为什么呢?因为对于任意的 $f_ax^a imes f_b x^b(a eq b)$ 必然对应一组 $f_bx^b imes f_a x^a$,所以系数一定是二的倍数,所以就只用考虑 $f_ix^i imes f_ix^i$ 这样的项。

  • 相关阅读:
    【转】go语言的字节序
    【转】Go maps in action
    angular 的进一步深入理解
    go 中goroutine 的使用
    hdu2516-取石子游戏 (斐波那契博弈)【博弈 二分查找】
    poj1067-取石子游戏 (威佐夫博弈)
    hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)
    hdu3999-The order of a Tree (二叉树的先序遍历)
    第二个MFC实例:GPA计算器
    第一个MFC实例:计算圆周长和圆面积
  • 原文地址:https://www.cnblogs.com/shzr/p/13373621.html
Copyright © 2011-2022 走看看