1. 程式人生 > >POJ - 3318 Matrix Multiplication (隨機演算法)

POJ - 3318 Matrix Multiplication (隨機演算法)

題意:

給出三個n*n的矩陣,問A*B=C時是否成立,要求演算法複雜度降低到O(n^3)

分析:

直接乘的話顯然複雜度不滿足,那麼可以構造一個n維列向量V,取隨機數0和1,如果A*B=C成立的話,那麼A*(B*V)=C*V也一定成立,但是如果A*B≠C成立的話,那麼也可能滿足A*(B*V)=C*V的情況成立,容易知道,滿足該條件的概率是1/2,那麼進行60次判定,誤判的可能性將降低到2的-60次方。

#include<cstdio>
#include<algorithm>
#include<ctime>
#include<climits>
#include<cstdlib>

using namespace std;

const int maxn=500+10;

int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],v[maxn],f[maxn],g[maxn];

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&a[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&b[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&c[i][j]);
        }
    }
    int  k;
    for(k=1;k<=60;k++){
        for(int i=1;i<=n;i++){
            v[i]=rand()%2;
        }
        for(int i=1;i<=n;i++){
            g[i]=0;
            for(int j=1;j<=n;j++){
                g[i]+=c[i][j]*v[j];
            }
        }
        for(int i=1;i<=n;i++){
            f[i]=0;
            for(int j=1;j<=n;j++){
                f[i]+=b[i][j]*v[j];
            }
        }
        for(int i=1;i<=n;i++){
            v[i]=f[i];
        }
        for(int i=1;i<=n;i++){
            f[i]=0;
            for(int j=1;j<=n;j++){
                f[i]+=a[i][j]*v[j];
            }
        }
        int i;
        for(i=1;i<=n;i++){
            if(f[i]!=g[i]) break;
        }

        if(i<=n) break;
    }
    if(k<=60) printf("NO\n");
    else printf("YES\n");
    return 0;
}