随机化算法,说白了,就是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;
}