zoukankan      html  css  js  c++  java
  • 洛谷P2144 [FJOI2007]轮状病毒

    可以用Matrix-Tree定理,然而被卡精度

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<iostream>
     6 #define MAXN 100+10
     7 #define EPS 0.00000001
     8 using namespace std;
     9 bool zero(double x){
    10     return (-EPS<x&&x<EPS);
    11 }
    12 double det(double a[MAXN][MAXN],int n){
    13     double b[MAXN][MAXN],ret=1;
    14     int sign=0;
    15     memcpy(b,a,sizeof(b));
    16     for(int i=1;i<=n;i++){
    17         if(zero(b[i][i])){
    18             int k=i;
    19             while(zero(b[k][i]))k++;
    20             if(k>n){
    21                 return 0;
    22             }
    23             for(int j=i;j<=n;j++){
    24                 swap(b[k][j],b[i][j]);
    25             }    
    26             sign++;
    27         }    
    28         ret*=b[i][i];
    29         for(int j=i+1;j<=n;j++){
    30             b[i][j]/=b[i][i];
    31         }
    32         for(int k=i+1;k<=n;k++){
    33             for(int j=i+1;j<=n;j++){
    34                 b[k][j]-=b[k][i]*b[i][j];
    35             }    
    36         }
    37     }
    38     if(sign&1){
    39         ret=-ret;
    40     }
    41     return ret;
    42 }
    43 double A[MAXN][MAXN];
    44 int v[MAXN];
    45 int n;
    46 void init(){
    47     v[1]=n;
    48     n++;
    49     for(int i=2;i<=n;i++){
    50         v[i]=3;
    51     }
    52     for(int i=1;i<=n;i++){
    53         for(int j=1;j<=n;j++){
    54             if(i==j){
    55                 A[i][j]=v[i];
    56             }    
    57             else{
    58                 if(i==1||j==1||i==n&&j==2||i==2&&j==n){
    59                     A[i][j]=-1;
    60                 }
    61                 else if(i-j==1||j-i==1){
    62                     A[i][j]=-1;
    63                 }
    64                 else{
    65                     A[i][j]=0;
    66                 }
    67             }
    68         }
    69     }
    70 }
    71 void solve(){
    72     printf("%.0f
    ",det(A,n-1));
    73 }
    74 int main()
    75 {
    76     scanf("%d",&n);
    77     if(n==1){
    78         printf("1
    ");
    79         return 0;    
    80     }
    81     if(n==2){
    82         printf("5
    ");    
    83         return 0;
    84     }
    85     init();
    86     solve();
    87     return 0;
    88 }
    View Code

    于是乎就乱推公式,得到

    轮状病毒的方案数满足递推式F(n) = 3 * F(n - 1) - F(n - 2) + 2,其中F(1) = 1, F(2) = 5

    加上高精度即可

  • 相关阅读:
    剑指offer系列0:替换空格&从头到尾打印链表
    算法1:动态规划
    设计模式2:策略模式
    NPOI导出xls、xlsx和csv
    EF6
    oracle导出数据字典
    oracle分组函数
    oracle分析函数中的开窗函数
    Oracle 列转行&行转列
    Oracle基本函数总结
  • 原文地址:https://www.cnblogs.com/w-h-h/p/8053977.html
Copyright © 2011-2022 走看看