• BZOJ1002: [FJOI2007]轮状病毒 (DP)


    标准做法似乎应该是计算生成树数量的基尔霍夫矩阵之类的..

    我看到的做法是一个神奇的高精度dp,当然以后这个blahblahblah矩阵还是要搞一下。。
     
     
    这个dp的原理就是把环拆成一条含特定点的链和剩下部分(可用dp解决),这样就避免了环具有的一些dp不好解决的奇怪判定.
    非常神奇
    %想出这个办法的dalao
     
    附上非常不走心的非常丑的自己的代码..
     
     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 using namespace std;
     8 int n;
     9 int f[110][2][35]={};//1 到i的单独一段都和中间连上了 0 到i的单独一段没有和中间连上
    10 int ans[35]={};
    11 int z[35]={};
    12 int a[35]={};
    13 int b[35]={};
    14 int w=0;
    15 void plu(){//a+b存z
    16     int e=0;
    17     for(int i=1;i<=30;i++){
    18         e=a[i]+b[i]+e;
    19         z[i]=e%10000;
    20         e/=10000;
    21     }
    22 }
    23 void mul(){//b*w存z
    24     int e=0;
    25     for(int i=1;i<=30;i++){
    26         e=w*b[i]+e;
    27         z[i]=e%10000;
    28         e/=10000;
    29     }
    30 }
    31 int main(){
    32     scanf("%d",&n);
    33     f[1][1][1]=f[1][0][1]=1;
    34     f[0][1][1]=1;
    35     for(int i=2;i<=n;i++){
    36         for(int j=1;j<=30;j++){
    37             a[j]=f[i-1][0][j];
    38             b[j]=f[i-1][1][j];
    39         }
    40         plu();
    41         for(int j=1;j<=30;j++){
    42             f[i][0][j]=z[j];
    43             z[j]=0;
    44         }
    45         
    46         w=2;
    47         mul();
    48         for(int j=1;j<=30;j++){
    49             b[j]=z[j];
    50             z[j]=0;
    51         }
    52         plu();
    53         for(int j=1;j<=30;j++){
    54             f[i][1][j]=z[j];
    55             z[j]=0;
    56         }
    57     }
    58     for(int i=1;i<=n;i++){
    59         w=i*i;
    60         for(int j=1;j<=30;j++){
    61             b[j]=f[n-i][1][j];
    62             a[j]=ans[j];
    63         }
    64         mul();
    65         for(int j=1;j<=30;j++){
    66             b[j]=z[j];
    67             z[j]=0;
    68         }
    69         plu();
    70         for(int j=1;j<=30;j++){
    71             ans[j]=z[j];
    72             z[j]=0;
    73         }
    74     }
    75     int f=0;
    76     for(int i=30;i>=1;i--){
    77         if(ans[i]!=0&&f==0){
    78             f=1;
    79             printf("%d",ans[i]);
    80             continue;
    81         }
    82         if(f){
    83             if(ans[i]>999){
    84                 cout<<ans[i];
    85             }
    86             else if(ans[i]>99){
    87                 cout<<0<<ans[i];
    88             }
    89             else if(ans[i]>9){
    90                 cout<<0<<0<<ans[i];
    91             }
    92             else{
    93                 cout<<0<<0<<0<<ans[i];
    94             }
    95         }
    96     }
    97     cout<<endl;
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    配置Log4j(非常具体)
    RapeLay(电车之狼R)的结局介绍 (隐藏结局攻略)
    普林斯顿公开课 算法1-11:并查集的应用
    检查Oracle 中死事务的语句
    app被Rejected 的各种原因翻译
    经典语录和思考总结
    Java实现夺冠概率模拟
    Java实现夺冠概率模拟
    Java实现打印回型嵌套
    Java实现打印回型嵌套
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7783854.html
Copyright © 2020-2023  润新知