• hdu4576 概率dp n^2的矩阵


    这个题目看网上好多题解都是直接O(n*m)卡过。我是这么做的。

    对于m次操作,统计每个w的次数。然后对每个w做矩阵乘法。

    这样直接做矩阵乘法是会TLE的。

    由于这里的矩阵很特殊,一次乘法可以降维成O(n^2)

    --------------------------

    怎么降维的可以这样模拟下:

    a b c      a b c     a*a+2bc  c*c+2ab   b*b+2ac

    c a b  *  c a b =  b*b+2ac  a*a+2bc  c*c+2ab

    b c a      b c a     c*c+2ab  b*b+2ac  a*a+2bc

    注意到原矩阵的每一行(除了第一行)都是上一行向右平移一个单位的结果,而相乘得到的矩阵也满足这个性质。

    那么做一次矩阵乘法的时候,就只用算出结果矩阵的第一行,然后下面的每一行直接可由上一行得到。

    复杂度降为了O(n^2)。

    -------------------------

    所以一个总的复杂度<O(n^2 * log1000000 * 100)=8千万.

    不到2000msAC了^_^

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<iomanip>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<set>
     7 #include<map>
     8 #include<queue>
     9 #include<stack>
    10 #include<string>
    11 #include<vector>
    12 #include<ctype.h>
    13 #include<algorithm>
    14 using namespace std;
    15 typedef long long LL;
    16 #define FF(i,x)    for(i=1;i<=x;i++)
    17 const int N = 205;
    18 
    19 double cMat[N][N],retMat[N][N];
    20 
    21 void matrixMul1(double A[][N],double B[][N],int a,int b)
    22 {
    23     double buff[N][N]={};
    24     int i,j,k;
    25     FF(i,a)    FF(k,a)    FF(j,b)
    26         buff[i][j] = buff[i][j] + A[i][k]*B[k][j];
    27     FF(i,a)    FF(j,b)    B[i][j]=buff[i][j];
    28 }
    29 
    30 void matrixMul2(double A[][N],double B[][N],int a,int b)
    31 {
    32     double buff[N][N]={};
    33     for(int j=1;j<=a;j++)
    34     {
    35         for(int k=1;k<=a;k++)
    36             buff[1][j]+=A[1][k]*B[k][j];
    37     }
    38     for(int i=2;i<=a;i++)
    39     {
    40         for(int j=2;j<=a;j++)    buff[i][j]=buff[i-1][j-1];
    41         buff[i][1]=buff[i-1][a];
    42     }
    43     int i,j;
    44     FF(i,a)    FF(j,b)    B[i][j]=buff[i][j];
    45 }
    46 
    47 void matrixFastPow(int p,int n)
    48 {
    49     for(;p;p>>=1)
    50     {
    51         if( p&1 )    matrixMul1(cMat,retMat,n,1);
    52         matrixMul2(cMat,cMat,n,n);
    53     }
    54 }
    55 
    56 int amount[105];
    57 
    58 int main()
    59 {
    60     int n,m,l,r;
    61     int w;
    62 
    63     while( scanf("%d%d%d%d",&n,&m,&l,&r),n||m||l||r )
    64     {
    65         memset(amount,0,sizeof(amount));
    66         for(int i=0;i<m;i++)
    67         {
    68             scanf("%d",&w);
    69             amount[w]++;
    70         }
    71         for(int i=1;i<=n;i++)
    72             if( i<l || i>r )    retMat[i][1]=0.0;
    73             else retMat[i][1]=1.0;
    74         for(int i=1;i<=100;i++)
    75             if( amount[i] )
    76             {
    77                 for(int p=1;p<=n;p++)
    78                     for(int q=1;q<=n;q++)
    79                         cMat[p][q]=0.0;
    80                 for(int j=1;j<=n;j++)
    81                 {
    82                     int a=(j-i);
    83                     while( a<=0 )    a+=n;
    84                     int b=(j+i);
    85                     while( b>n )    b-=n;
    86                     cMat[j][a]+=0.5;
    87                     cMat[j][b]+=0.5;
    88                 }
    89                 matrixFastPow(amount[i],n);
    90             }
    91 
    92         printf("%.4f
    ",retMat[1][1]);
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    POI向Excel的单元格中写入图片
    POI导出excel提示ClassNotFoundException: org.apache.commons.codec.digest.DigestUtils
    POI设置Excel单元格样式
    MySQL数据库删除重复数据
    NAVICAT FOR MYSQL 快捷键
    【Eclipse】系统切换JDK版本后,Eclipse中出现JDK版本不一致的错误
    jxl导入Excel文件抛出java.lang.StringIndexOutOfBoundsException异常
    MySQL数据库
    jquery DOM操作
    触发事件
  • 原文地址:https://www.cnblogs.com/kiwi-bird/p/3250696.html
Copyright © 2020-2023  润新知