码迷,mamicode.com
首页 > 其他好文 > 详细

Holiday 8

时间:2018-02-16 21:36:17      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:namespace   algo   show   http   世界杯   相等   family   cpp   div   

  今天是大年初一,但是我的心情并不怎么样。感觉过年了老家人也多了,人多了就不清净了。也不会浮躁,就是心里老是烦。这两天的学习效率远比不上之前,得赶紧调整。

  今天结了概率一章的内容,最后的两道例题都没看懂,概率还需要继续学习积累沉淀。

  POJ3071 Football (http://poj.org/problem?id=3071)

  与其说是DP,更像是递推,递推方程很好想,关键在于计算第i轮第k支球队可能碰到的对手,书上的计算方式看不懂,网上也找了不少博客,都大同小异。之后突然就茅塞顿开。首先很容易发现第i轮k的对手是从某个队伍j开始的连续2i-1支球队,这样只要找到这个起始对手j就可以做了。如何找j?为了方便找规律,队伍从0开始编号,为什么?因为牵扯到二进制,如果从1开始编号,那么最后一支球队会成为所有球队中唯一一支二进制位数为n的球队,那么在进行移位操作时就会造成不统一,这也是网上的算法都是 (i-1)>>1^1=(j-1)>>1的原因。所以从0开始编号更符合计算机的思维。这样一来我们尝试找规律。在第一轮两支交战队伍(i,j)满足i^1=j。第二轮(i,j)满足(i>>1^1=j>>1)。第三轮(i,j)满足(i>>2^1=j>>2)......化为一般形式,在第i轮交战的双方必须满足(p>>(i-1)^1=q>>(i-1))。形象的理解就是我们考虑第i轮的交战双方时就略去所有之前的二进制位,略去之后两支球队相邻那么在第i轮他们就可以对战。我们第二重循环枚举的是每支球队,网上有算法是对于球队i,再开一重循环枚举所有的球队j,判断是否满足上述条件。这样无疑会提高程序的运行时间,就比如说在第一轮时,每支球队只可能有一个对手,而该算法将枚举2n支球队。这也是对题目理解不透彻的结果。一开始我们就说了,会是连续的球队,因此我们只要用以下方式找出起始的球队j就好了。j=(k>>(i-1)^1<<(i-1))。这样就保证了所有枚举到的球队在二进制第i位是与k互异且比i高的进制位值是相同的的。

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int M=1<<7;
double dp[M+7][M+7],p[M+7][M+7];
int main() {
	int n;
	while(scanf("%d",&n)==1) {
		if(n==-1) break;
		memset(dp,0,sizeof(dp));
		int m=1<<n;
		for(int i=0;i<m;i++)
			for(int j=0;j<m;j++)
				scanf("%lf",&p[i][j]);
		for(int i=0;i<m;i++)
			dp[0][i]=1;
		for(int i=1;i<=n;i++) 
			for(int j=0;j<m;j++) {
				int l=(j>>i-1^1)<<(i-1);
				int r=l+(1<<i-1);
				for(int k=l;k<r;k++) 
					dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];
			}
		double ans=0;
		int team=0;
		for(int i=0;i<m;i++) 
			if(dp[n][i]>ans) {
				ans=dp[n][i];
				team=i;
			}
		printf("%d\n",team+1);
	}
	return 0;
}

 

 

  洛谷1291 [SHOI2002]百事世界杯之旅 (https://www.luogu.org/problemnew/show/P1291)

  公式还可以,要注意通分约分的过程。

  POJ2454 Jersey Politics (http://poj.org/problem?id=2454)

  随机算法,先从小到大排序,然后选出前2*k个数划分成两个集合,再随机交换两个集合中的元素直到满足条件为止。

  POJ3318 Matrix Multiplication (http://poj.org/problem?id=3318)

  Ο(n3)直接矩阵乘法会TLE,问题就在于我们并不需要计算出实际的结果,只要检验给的结果是否正确。就像NOIP某年的等价表达式那道题一样,我们不需要真的需判断表达式是否等价,只要带几个数检验一下就行了。同样的思想,之所以复杂度高是因为我们对两个n*n的矩阵进行相乘,而等号两边同乘一个数等号依然成立,对于矩阵,我们就同乘一个矩阵,为了优化复杂度同时满足矩阵乘法的条件,很容易想到用一个n*1的检验矩阵。这样矩阵相乘的时间就是Ο(n2)的了,再Ο(n)比较乘出来的结果是否相等。检验矩阵的元素应该随机的,检验矩阵的个数就是算法总时间复杂度的常数,在不清楚概率的情况下,可以根据数据确定一个保证不超时的次数。

  今天本来还有一道概率题是用模拟退火和爬山算法做的物理题,感觉网上的模拟退火都很虚,以后再写吧。其实晚上本来还准备写Splay的,但是感觉会调很长时间,那就又不能按时睡觉了,明天又要困了,今天为啥我没空写数据结构,因为我吃完饭从一点一下睡到五点,眼睛真的睁不开啊,根本不想看屏幕。

  “每一次深情眼光的背后,谁知道会有多少愁。”

 

Holiday 8

标签:namespace   algo   show   http   世界杯   相等   family   cpp   div   

原文地址:https://www.cnblogs.com/qjs12/p/8450490.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!