随机化算法小结

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值