隨機化算法,說白了,就是rand()函數的恰當運用,利用每次得到的不同數字
進行組合或者其他應用,使得隨機數成爲貪心的變型,更快找到答案。
在一些題目給出的條件很少的情況下,可以利用隨機化算法減少時間用量。
poj 3318
題目大意:給出兩個同爲N階矩陣的A和B,以及C 判斷A*B~C是否相等
思 路:如果只是簡單的A*B 則矩陣相乘計算起來是比較麻煩的,
這時候可以藉助Nx1矩陣D進行轉換--A*B*D=A*(B*D)
則右邊也可以轉爲C*D
此時只要判斷A*(B*D)~~~~~C*D的關係,並且此時均爲Nx1
矩陣,如此將N*N個數轉爲N個數的比較。
D矩陣可以根據rand()函數得到N個數即可。
代碼如下:
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <limits.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <functional>
using namespace std;
#define s 505
long long a[s][s],b[s][s],c[s][s],x[s];
int t;
void init(long long example[s][s])
{
for(int i=1;i<=t;i++)
for(int j=1;j<=t;j++)
scanf("%I64d",&example[i][j]);
}
void work(long long a[s][s],long long b[s],long long c[s])
{
int i,j;
for(i=1;i<=t;i++)
{
c[i]=0;
for(j=1;j<=t;j++)
c[i]+=a[i][j]*b[j];
}
}
bool check(long long p1[s],long long p2[s])
{
for(int i=1;i<=t;i++)
if(p1[i]!=p2[i])
return false;
return true;
}
int main()
{
int i,j;
long long p[s],p1[s],p2[s];
scanf("%d",&t);
init(a),init(b),init(c);
for(i=1;i<=t;i++)
x[i]=rand()%1000+1;
work(b,x,p);
work(a,p,p1);
work(c,x,p2);
bool flag=check(p1,p2);
if(!flag){
printf("NO\n");return 0;}
else
printf("YES\n");
}
poj2454
題目大意:給出3*k個數,要求將他們分成三份,使得至少有兩份之和
大於2*k*500 即兩份中的每一份都大於500*k
思 路:題目給出的條件很少,適合用隨機化方法。首先得到的3*k
個數進行排序後將最小的K個數排出,之後在剩餘的 2*k個數
中進行兩兩組合直至符合條件爲止。
這道題剛開始做的時候用了兩個數組,結果超時。。。
需要開設一個結構體進行排序,理論上應該更節省時間。
代碼如下:
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <limits.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <functional>
using namespace std;
#define N 66
typedef struct {
int data,num;
}Node;
Node node[N*3];
bool cmp(Node a,Node b)
{
return a.data<b.data;
}
int main()
{
int i,k;
scanf("%d",&k);
for(i=1;i<=3*k;i++)
{
scanf("%d",&node[i].data);
node[i].num=i;
}
sort(node+1,node+3*k+1,cmp);
int sa=0,sb=0;
for(i=k+1;i<=2*k;i++)
sa+=node[i].data;
for(i=2*k+1;i<=3*k;i++)
sb+=node[i].data;
while(sa<=500*k||sb<=500*k)
{
int a=rand()%k+k+1;
int b=rand()%k+2*k+1;
sa=sa-node[a].data+node[b].data;
sb=sb-node[b].data+node[a].data;
swap(node[a],node[b]);
}
for(i=1;i<=3*k;i++)
printf("%d\n",node[i].num);
return 0;
}