紫书-第10章-数学概念与方法
文章平均质量分 56
冷月残星
这个作者很懒,什么都没留下…
展开
-
gcd,枚举,数学(高速公路,uva 1393)
枚举所有类型的对角线,计算出每种对角线的总个数,注意不要重复计算。包围盒这个思想很不错。先算总的,再减去重复的。因为总的也好算,重复的也好算。#include#define maxn 310using namespace std;int n,m;int GCD[maxn][maxn];int gcd(int a,int b){ return a%b==0?b:g原创 2016-10-22 09:09:02 · 344 阅读 · 0 评论 -
概率DP,记忆化搜索(纸牌游戏,uva 1637)
有时候编码解码映射太麻烦,干脆多开几维数组得了。搜索的话可以考虑用记忆化。#includeusing namespace std;char pai[9][4];int kase;int vis[5][5][5][5][5][5][5][5][5];double d[5][5][5][5][5][5][5][5][5];double dp(int a1,int a2,in原创 2016-09-28 22:10:00 · 456 阅读 · 0 评论 -
动态规划,递推(杆子的排列,uva 1638)
一开始用排列组合做,写完了后才发现是错的,虽然能过样例。以后一定要先确定解法正确,再编写代码。否则简直浪费时间。最后看了书是用动态规划。动态规划的特点就是有状态和决策。我们可以通过在某个状态上的某个位子放一个杆子来转移到下一个状态。紫书上说杆子的具体高度不影响结果,我的理解就是你只用知道所有杆子的长度不同,长和短是相对而言的,题目要求你出所有不同长短关系的序列。我们发现通过放一原创 2016-09-29 13:53:37 · 732 阅读 · 0 评论 -
全期望(过河,uva 12230)
#includeusing namespace std;int n;int kase;int D;double p[15];double L[15];double v[15];int main(){ while(~scanf("%d %d",&n,&D)&&(n+D)) { double ans=0; for(int i=1;i原创 2016-09-29 15:45:54 · 455 阅读 · 0 评论 -
求期望,对数的应用,预处理(糖果,uva 1639)
思路有,但一看到n那么大,就不会做了。。。利用对数来计算期望,以保证精度。学到了!然后。。一定要先证明自己的数学公式一定是对的,再去编写代码,否则就是白费时间。0的对数是负无穷,所以要特殊判断,不过不判断也不会错。预处理时打表,以快速求出log(C(m,n))。也就是带了对数而且允许误差才能这么算吧。第一次见到卡long double的。。。cb没法正确的输原创 2016-09-29 17:59:50 · 1364 阅读 · 0 评论 -
递推,计数(危险的组合,uva 580)
#includeusing namespace std;typedef long long ll;ll dp[35];ll mypow(ll x,ll n){ ll ret=1; while(n) { if(n&1) ret*=x; x*=x; n>>=1; } return ret;}vo原创 2016-09-29 12:20:16 · 490 阅读 · 0 评论 -
数学期望(优惠券,uva 10288)
要先求出有n种图案,已拥有k种,平均拿几次就能获得一种新图案。累加起来就是答案。那怎么求平均拿几次就能获得一种新图案呢?我们设拿到一种新图案需要次数t的概率为p,令s=k/n很容易求得p=s^(t-1)*(1-s)。累加t到正无穷。发现是一个差比数列,计算出平均拿n/(n-k)能获得一种新图案。代码#includeusing namespace std;typedef lo原创 2016-10-02 18:39:08 · 416 阅读 · 0 评论 -
连续概率(概率,uva 11346)
又读错题,浪费大量时间,好久没碰数分,连最简单的积分都不熟练了= =。求概率转化为求面积比,要用到积分。求面积用割补法,因为直接算不方便积分。极端情况要特殊处理,如0%或100%的时候。#includeusing namespace std;double a,b,s;int main(){ int t; scanf("%d",&t);原创 2016-10-03 12:31:36 · 420 阅读 · 0 评论 -
递推,概率DP,概率(你想当2^n元富翁吗?,uva 10900)
http://blog.csdn.net/yeyeyeguoguo/article/details/43503277其实每个问题都一模一样,答不答只看你现在已拥有多少钱。其实已拥有多少钱是固定的,所以只看概率。dp[i]就是回答完前i题的期望。显然能答到第i题,那么前面的题肯定都答对了,因此影响期望的只能是后面的题目了。所以要从后往前推。答对的概率是在[t,1]转载 2016-10-03 14:32:20 · 355 阅读 · 0 评论 -
概率(多边形,uva 11971)
#includeusing namespace std;typedef long long ll;ll mypow(ll x,ll n){ ll ret=1; while(n) { if(n&1) ret*=x; x*=x; n>>=1; } return ret;}ll gcd(ll a,ll原创 2016-10-03 22:58:51 · 403 阅读 · 0 评论 -
找规律(约瑟夫的数论问题,uva 1363)
感觉你现在的知识储备还可以了,问题在于如何做题。很多时候题目都不是模板题,不是说你一定要知道某个经典算法才能做的。大部分时候都是依靠着基础的算法,自己创造出一个解决办法。这就需要对基础知识掌握得十分牢固以及大量的做题思考后才能达到。希望自己以后做题要多乱搞,或者说多分析思考,而不是总想着套什么算法。找规律就是一种乱搞,能优化时间复杂度。至于怎么想到答案,我只能说,就认真想就好了。认原创 2016-10-20 15:22:19 · 760 阅读 · 0 评论 -
筛法,欧拉函数,递推(帮帮Tomisu,uva 11440)
x的所有素因子都大于M ==> x与M!互质。若x>M!,那么x与M!互质 ==> x%(M!)与M!互质。因为M如何求M!的欧拉函数呢?用递推的方法。phi[i]表示i!的欧拉函数。phi[1]=phi[2]=1; for(ll i=3;i<=n;i++) if(vis[i]) phi[i]=phi[i-1]*i原创 2016-10-20 16:49:19 · 406 阅读 · 0 评论 -
枚举,预处理,条件概率(条件概率,uva 11181)
#includeusing namespace std;int N,r;int kase;double sum[25];double p[25];bool st[25];double tot;void dfs(int n,int r){ if(n==0) { if(r!=0) return; double ans=1;原创 2016-09-28 21:04:17 · 275 阅读 · 0 评论 -
水题(奶牛和轿车,uva 10491)
#includeusing namespace std;int main(){ double a,b,c; while(scanf("%lf %lf %lf",&a,&b,&c)!=EOF) { double niu=a/(a+b); double che=b/(a+b); double ans=niu*(b)/(a+原创 2016-09-28 20:44:27 · 278 阅读 · 0 评论 -
水题(决斗,uva 1636)
#includeusing namespace std;char str[110];int main(){ while(scanf("%s",str)!=EOF) { int l=strlen(str); int kong=0; int st=0; for(int i=0;i原创 2016-09-28 20:34:13 · 409 阅读 · 0 评论 -
gcd,高效(魔法GCD,uva 1642)
感觉前面高效算法设计白学了,除了O(n^2)和一些乱七八糟的想法外什么都不知道。枚举j,快速找出最优的i。一边枚举j,一边更新查找表。每次遍历查找表寻找最优的i即可。查找表一开始还用set搞来搞去。代码又麻烦,速度也不快。其实对于这种需要频繁更新和删减的,不如重开一个vector,把更新后的内容放在里面,再赋值给原vector。然后数据范围要用long long。gcd(a原创 2016-10-22 10:31:45 · 587 阅读 · 0 评论 -
找规律,数学(巨大的斐波那契数列,uva 11582)
18446744073709551615=2^64-1是unsigned long long能表示的最大的数,输入输出用%llu或%I64u。发现很多数学题都是要你找规律的,只不过要注意特殊数据。#includeusing namespace std;typedef unsigned long long ll;vectorf[1010];void init(){原创 2016-09-26 23:44:23 · 1376 阅读 · 0 评论 -
扩展欧几里得算法(不爽的裁判,uva 12169)
http://blog.csdn.net/a197p/article/details/45418367一般这种数论的题,要注意中间变量或不会爆int。最好就全部都用long long,就没事了。这种类型的题目主要就是推等式,然后上算法。做了挺多这种题的了。怎么推出等式是难点,要多去尝试带入,消元之类的。然后再观察吧。a的范围小,所以可以枚举。主要是取余10001所以转载 2016-09-27 01:11:42 · 540 阅读 · 0 评论 -
筛法求素数,组合数公式,唯一分解定理(选择与除法,uva 10375)
#includeusing namespace std;bool vis[10010];vectorprm;int e[1300];int p,q,r,s;void init(){ int m=sqrt(10000+0.5); for(int i=2;i<=m;i++) if(!vis[i]) for(int j=i*i;j<=10000;j+=i原创 2016-09-27 10:40:16 · 461 阅读 · 0 评论 -
筛法求素数,唯一分解定理(最小公倍数的最小和,uva 10791)
显然同样多的数,乘起来肯定比加起来大。所以我们会尽量把他们加起来。由于是最小公倍数,所以指数必须要取到最大值,否则最小公倍数就不是他了。这就是为什么每个aipi作为一个单独的整数时最优。确实有很多陷阱,n=1特殊数据。如果因子的种数只有1个那就直接输出n+1。注意是因子的种数,不是个数。因为每个因子一定要取指数最大的那个。因此有多少种因子就有多少个整数,要求至少两个整数,所以另一个一定是1。自原创 2016-09-27 12:30:22 · 745 阅读 · 0 评论 -
平面的图欧拉公式(多少块土地,uva 10213)
用C++高精度模板超时= =。第一次用JAVA交题,CE两次= =。看紫书把= =。import java.math.BigInteger;import java.util.*;public class Main{ Main() { Scanner in=new Scanner(System.in); int T_T=in.nextInt(); whil转载 2016-10-21 21:33:06 · 591 阅读 · 0 评论 -
数论,优化,预处理(GCD 等于 XOR,uva 12716)
能想到O(n(logn)^2)就差不多了,至于O(nlogn)真的好难想到。。。只能说先暴力,然后再找规律不失为一个好方法吧。类似素数筛法的算法的复杂度都是O(nlogn)。因为n/2+n/3+...+n/n=n*(1/2+1/3+...+1/n)。根据调和级数的性质,1/2+1/3+...+1/n约等于lnn。所以复杂度为O(nlogn)。具体思路看紫书吧。预处理的技巧也非常转载 2016-09-27 20:10:12 · 496 阅读 · 0 评论 -
数学(统计问题,uva 1640)
http://blog.csdn.net/u014800748/article/details/43956019看别人写的才会,没有用紫书上的方法。感觉自己数位DP,或者说这些数位相关问题很弱。还记得紫书上的一题《颜色的长度》,里面讲到用一种技巧,那就是计算还需要多少费用。这题里也有类似的感觉,比如说你要求n的答案是多少,那么就先计算个位产生了多少影响,然后n/=10,递归转载 2016-10-13 20:07:24 · 465 阅读 · 0 评论 -
唯一分解式,二项式定理(无关的元素,uva 1635)
WA,找了好久。。。if(n!=1) { PRM.push_back(m); e[PRM.size()-1]++; }改成if(n!=1) { PRM.push_back(n); e[PRM.size()-1]++; }就OK了。还是在找约数的地方容易错啊。前面几道题这里也出了小问题原创 2016-09-28 12:59:46 · 503 阅读 · 0 评论 -
欧拉函数(交表,uva 10820)
http://blog.csdn.net/lyhvoyage/article/details/9734219把问题转化求1~n之间共有多少对互质的数。真的,以后做题应该先动动脑子再开始写,不要就直接开始无脑做。多想想问题可不可以转化或者化简,再想解决办法,然后好好分析算法时间空间复杂度,最后才开始写。欧拉函数,再求一下和就OK了。前面做过一道很像的题,我是说打表的思转载 2016-09-28 14:03:03 · 343 阅读 · 0 评论 -
找第k大的东西(密码,uva 1262)
#includeusing namespace std;int K;char J1[10][10];char J2[10][10];setSET[3][10];int num[10];int sum[10];vectorans;int main(){ int T; scanf("%d",&T); while(T--) { s原创 2016-09-28 20:02:24 · 297 阅读 · 0 评论 -
欧拉函数(森林里的树,uva 10214)
求小于等于n中互质的数的对数,可以用欧拉函数。但是如果两个数互质的数的取值范围不同,就有一个小技巧。紫书上讲的很清楚了。#includeusing namespace std;typedef long long ll;ll phi[2010];ll a,b;ll ans;void init(){ phi[1]=1; for(ll i=2;i<=2000原创 2016-10-20 20:19:55 · 412 阅读 · 0 评论