浅浅地谈一下随机算法【poj2454】【poj3318】
随机算法我也只是稍微接触了一下,就是想写篇博客自己稍微总结一下
其实随机算法也算是一个玄学吧,运气不好还是会wa。但是我们知道,计算机可以在短时间内计算大量的数据,所以碰到正确答案的概率还是挺大的。
当然随机不是随机答案啦,对于不同的题有可以不同的随机对象。通常我们会在一下情况下用随机:
1、逐个枚举太多无用的情况下选择随机 以减少枚举次数
2、判断正确性的时候降低暴力判断的复杂度
下面还是放题吧
poj2454 Jersey Politics
Description
In the newest census of Jersey Cows and Holstein Cows, Wisconsin cows have earned three stalls in the Barn of Representatives. The Jersey Cows currently control the state’s redistricting committee. They want to partition the state into three equally sized voting districts such that the Jersey Cows are guaranteed to win elections in at least two of the districts.
Wisconsin has 3*K (1 <= K <= 60) cities of 1,000 cows, numbered 1..3*K, each with a known number (range: 0..1,000) of Jersey Cows. Find a way to partition the state into three districts, each with K cities, such that the Jersey Cows have the majority percentage in at least two of districts.
All supplied input datasets are solvable.
Input
* Line 1: A single integer, K
* Lines 2..3*K+1: One integer per line, the number of cows in each city that are Jersey Cows. Line i+1 contains city i’s cow census.
Output
* Lines 1..K: K lines that are the city numbers in district one, one per line
* Lines K+1..2K: K lines that are the city numbers in district two, one per line
* Lines 2K+1..3K: K lines that are the city numbers in district three, one per line
Sample Input
2
510
500
500
670
400
310
Sample Output
1
2
3
6
5
4
Hint
Other solutions might be possible. Note that “2 3” would NOT be a district won by the Jerseys, as they would be exactly half of the cows.
translate
在泽西奶牛和荷斯坦奶牛的最新普查中,威斯康星奶牛在谷仓中获得了三个档位。 泽西奶牛目前控制着国家重新分配委员会。 他们想将国家分为三个相当大的投票地区,以便保证泽西奶牛在至少两个地区获得选举权。
威斯康星州有3 * K(1 <= K = = 60)个1000头牛的城市,编号为1..3 * K,每头都有泽西奶牛的已知数量(范围:1.001)。 找到一种将州划分为三个区域的方式,每个区域都有K个城市,使得泽西奶牛在至少两个地区拥有多数比例。
所有提供的输入数据集都可以解决。
首先有一个贪心:把序列从大到小排序,取前2*k个作为需要满足要求的两个子序列的元素。之后就是对于这2*k个元素如何分配的问题了
如果dfs的话会出事(这是肯定的),那么如何减少枚举次数呢?就是用随机算法了
但是如何随机也是有讲究的。如果我们直接随机这个序列,很有可能两个子序列的元素并没有改变(只是交换了一下顺序)。我们希望每一次的枚举都有效,即交换元素。那么很显然,随机这个交换的元素就好了
#include<ctime>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int val,num;
}a[200];
int k;
bool cmp(const node &x,const node &y){
return x.val>y.val;
}
int main(){
srand((unsigned)time(NULL));
while(scanf("%d",&k)!=EOF){
for(int i=0;i<3*k;i++){
scanf("%d",&a[i].val);
a[i].num=i;
}
sort(a+0,a+3*k,cmp);
int sum1=0,sum2=0;
for(int i=0;i<k;i++){
sum1+=a[i].val;
sum2+=a[i+k].val;
}
while(1){
if(sum1>500*k&&sum2>500*k) break;
int r1=rand()%k,r2=rand()%k;
sum1=sum1-a[r1].val+a[k+r2].val;
sum2=sum2-a[k+r2].val+a[r1].val;
swap(a[r1],a[k+r2]);
}
for(int i=0;i<3*k;i++) printf("%d\n",a[i].num+1);
}
return 0;
}
poj3318 Matrix Multiplication
Description
You are given three n × n matrices A, B and C. Does the equation A × B = C hold true?
Input
The first line of input contains a positive integer n (n ≤ 500) followed by the the three matrices A, B and C respectively. Each matrix’s description is a block of n × n integers.
It guarantees that the elements of A and B are less than 100 in absolute value and elements of C are less than 10,000,000 in absolute value.
Output
Output “YES” if the equation holds true, otherwise “NO”.
Sample Input
2
1 0
2 3
5 1
0 8
5 1
10 26
Sample Output
YES
Hint
Multiple inputs will be tested. So O(n3) algorithm will get TLE.
translate
给定三个n×n矩阵A,B和C.方程A×B = C是否成立?
题目的hint说了,暴力的把矩阵乘起来要炸。
那么如果可以找到一个快速的判断方法,不一定要对错两面都具有绝对性,只要其中一面具有绝对性就好。
设v为随机生成的n维列向量,每个元素取1或0。看A*(B*v)和C*v是否相同。但是这样不稳定,因为即使A*B不等于C,这样算出来可能是相等的。经计算,这种情况还相等的概率小于1/2。那么多判断几次,出错的概率就会大大降低。所以试60次就差不多了
#include<ctime>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
struct matrix{
int k[505][505];
int x,y;
}A,B,C,v,_B,_C,_A;
void get_rand(matrix &v){
for(int i=1;i<=n;i++) v.k[i][1]=rand()%2;
}
void mult_mt(matrix &_a,const matrix &a,const matrix &v){
_a.x=a.x,_a.y=v.y;
for(int i=1;i<=n;i++){
int tmp=0;
for(int j=1;j<=n;j++)
tmp+=a.k[i][j]*v.k[j][1];
_a.k[i][1]=tmp;
}
}
bool check(const matrix &a,const matrix &b){
for(int i=1;i<=n;i++) if(a.k[i][1]!=b.k[i][1]) return false;
return true;
}
int main(){
srand((unsigned)time(NULL));
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) scanf("%d",&A.k[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) scanf("%d",&B.k[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) scanf("%d",&C.k[i][j]);
A.x=A.y=B.x=B.y=C.x=C.y=n;
int m=60;
v.x=n,v.y=1;
while(m--){
get_rand(v);
mult_mt(_B,B,v);
mult_mt(_C,C,v);
mult_mt(_A,A,_B);
if(!check(_C,_A)){
printf("NO\n");
return 0;
}
}
printf("YES\n");
return 0;
}
浅浅地谈一下随机算法【poj2454】【poj3318】的更多相关文章
- 浅谈URLEncoder编码算法
一.为什么要用URLEncoder 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将 ...
- 浅谈Hex编码算法
一.什么是Hex 将每一个字节表示的十六进制表示的内容,用字符串来显示. 二.作用 将不可见的,复杂的字节数组数据,转换为可显示的字符串数据 类似于Base64编码算法 区别:Base64将三个字节转 ...
- 浅谈Base64编码算法
一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...
- 浅谈关于特征选择算法与Relief的实现
一. 背景 1) 问题 在机器学习的实际应用中,特征数量可能较多,其中可能存在不相关的特征,特征之间也可能存在相关性,容易导致如下的后果: 1. 特征个数越多,分析特征.训练模型所需的时间就越 ...
- 从决策树学习谈到贝叶斯分类算法、EM、HMM --别人的,拷来看看
从决策树学习谈到贝叶斯分类算法.EM.HMM 引言 最近在面试中,除了基础 & 算法 & 项目之外,经常被问到或被要求介绍和描述下自己所知道的几种分类或聚类算法(当然,这完全 ...
- 从决策树学习谈到贝叶斯分类算法、EM、HMM
从决策树学习谈到贝叶斯分类算法.EM.HMM (Machine Learning & Recommend Search交流新群:172114338) 引言 log ...
- 微信红包中使用的技术:AA收款+随机算法
除夕夜你领到红包了吗?有的说“我领了好几K!”“我领了几W!” 土豪何其多,苦逼也不少!有的说“我出来工作了,没压岁钱了,还要发红包”.那您有去抢微信红包吗?微信群中抢“新年红包”春节爆红.618微信 ...
- POJ 3318 Matrix Multiplication(随机算法)
题目链接 随机算法使劲水...srand((unsigned)time(0))比srand(NULL)靠谱很多,可能是更加随机. #include <cstdio> #include &l ...
- 抽奖随机算法的技术探讨与C#实现
一.模拟客户需求 1.1 客户A需求:要求每次都按照下图的概率随机,数量不限,每个用户只能抽一次,抽奖结果的分布与抽奖概率近似. 1.2 客户B需求:固定奖项10个,抽奖次数不限,每个用户只能抽一次, ...
随机推荐
- python 学习分享-socket编程
socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意思. 通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟 ...
- Python全栈工程师(编码)
ParisGabriel Python 入门基础 补充: 主流3操作大系统 Windows: Winxp Win7 Win8 Win10 Unix: Solaris(SUN) IO ...
- Vue-cli 本地开发请求https 接口 DEPTH_ZERO_SELF_SIGNED_CERT
环境:npm run dev 本地开发连接后台的开发环境的接口. 贴上proxyTable 的转发(代理?反向?这个具体叫什么不明白...) proxyTable: { "/api" ...
- c#用UpdatePanel实现接局部刷新
通常我们看到局部刷新就会想到Ajax,但是我今天要说的是c#的一个控件,只要把服务器按钮和要刷新的区域放在该控件内就能实现局部刷新. 当然它必须和ScriptManager控件一起使用. Update ...
- (转)彻底隐藏Nginx版本号的安全性与方法
Nginx默认是显示版本号的,如: [root@bkjz ~]# curl -I www.nginx.orgHTTP/1.1 200 OKServer: nginx/0.8.44Date: Tue, ...
- 【Luogu】P4103大工程(虚树DP)
题目链接 我貌似发现这类DP就是先别管什么虚树……把树形DP搞出来套上虚树板子就好了 这个树形DP就是设sum为答案,sumd为子树内所有点的深度和(当然指的是被询问的点),maxi指子树内最深的点的 ...
- TensorFlow应用实战 | TensorFlow基础知识
挺长的~超出估计值了~预计阅读时间20分钟. 从helloworld开始 mkdir 1.helloworld cd 1.helloworldvim helloworld.py 代码: # -*- c ...
- 寻宝游戏(bzoj 3991)
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可 ...
- Selenium2 鼠标悬停效果实现
对一些js控件,鼠标悬停的时候出发下拉层的实现 1.使用Action public void moveToElement(WebDriver driver, By locator) { Actions ...
- MFC下CSocket编程详解(转)
原文转自 http://blog.csdn.net/yejiansnake/article/details/2175778 MFC下CSocket编程详解: 1. 常用的函数和注意事项(详细的函数接口 ...