思维题
文章平均质量分 58
skajre
这个作者很懒,什么都没留下…
展开
-
HDU 1703 PBD(递推)
假设当人数是x时,传递完成需要f次,那么添加一个人时,只需要把新的人与任意一个人连接,那么这个人带有了新人的信息,然后再进行f次,旧的人都带有所有人的信息,新人再与任意一个人连接即可,f[n]=f[n-1]+2。#includeusing namespace std;const int maxn=10000+5;int f[maxn]={0,0,1,3,4};int main(){原创 2017-01-24 15:22:45 · 301 阅读 · 0 评论 -
UVA 12235 Help Bubu(状压dp)***
这是目前碰到最难的dp题之一,看题解都看得迷迷糊糊的。现在是定义状态dp[i][j][s][x],代表前i本书,拿走了j本书,s是剩下书的集合,x是最后一本书的高度的混乱度。为了省空间,第一维可以用滚动数组。然后依次枚举第二三四维,如果目前的高度h与x相同,那直接从i-1继承过来即可,如果不相同,那就有两种选择,一种选择是拿走这本书,另一种选择是把这本书放进去。#include#原创 2016-10-18 22:52:00 · 249 阅读 · 0 评论 -
UVA 11134 Fabled Rocks(贪心)
这题的行和列其实是没有关系的,固定了行之后对于固定列是没有影响的,那么就可以分开来考虑。那么考虑行和列的时候就需要贪心来排序了,思想是优先排到自己有的地方别人没有的,所以如果从前往后排,排序的条件就是r小的排前面,如果r相同,l小的排前面,如果从后往前排,那么r大的排前面,r相同l大的排前面。#include#include#include#includeusing namespace s原创 2016-10-05 09:45:18 · 214 阅读 · 0 评论 -
UVA 10559 Blocks(记忆化dp)
这题在poj上做过,之前的博客已经有详细解释了。#include#include#include#include#includeusing namespace std;#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define ss(x) scanf("%d",&x)const int maxn=200+10;struct bloc原创 2016-10-18 18:28:55 · 244 阅读 · 0 评论 -
UVA 1407 Caves(树形dp)
这题定义状态f[i][j][0]和f[i][j][1]。f[i][j][0]表示遍历以i为根节点的子树的j个节点并且不回到节点i,那么状态方程为f[i][j][0]=min(f[i][j][0],min(f[i][j-k][1]+f[v][k][0]+w,f[i][j-k][0]+f[v][k][1]+2*w);f[i][j][1]表示遍历以i为根节点的子树的j个节点并且回到节点i,那么状原创 2016-10-18 16:48:34 · 253 阅读 · 0 评论 -
UVA 1456 Cellular Network(dp)
这题一开始看到什么数学期望,没敢做,放倒最后才做,没想到这么水= =。#include#include#include#includeusing namespace std;#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define ss(x) scanf("%d",&x)const int maxn=100+10;int u[max原创 2016-10-17 22:06:37 · 222 阅读 · 0 评论 -
UVA 10564 Paths through Hourglass(dp)
这题状态挺好想的,但是写得我吐血,一开始从上往下的,写到崩溃,一直无法输出正确答案,代码又太烦,删了重写了从下往上的,然后输出只需要简单的搜索就行了,唯一需要注意点的就是dp数组和记录答案的变量都要开long long型。#include#include#include#includeusing namespace std;#define rep(i,a,b) for(int i=(原创 2016-10-17 20:58:41 · 185 阅读 · 0 评论 -
UVA 10891 Game of Sum(区间博弈dp)***
首先是博弈的思想,用两个for循环枚举给对手剩下的子序列,然后对手取的也是最优,这时候返回的值就是对手最优的值,但是如果对手取的值是正的,那么表明我再取能把对手取的正值放到我这里,我能够更优,直到对手最优只能是负值时,如果对手无论如何最优不能取负值,那么我就把序列全部取完,我一定是最优的,其本质还是极大极小搜索。//// main.cpp// Richard//// Create原创 2016-10-03 11:04:27 · 414 阅读 · 0 评论 -
UVA 10635 Prince and Princess(LCS转LIS)
如果LCS的元素两两都不相同,可以转成LIS的nlogn做法。//// main.cpp// Richard//// Created by 邵金杰 on 16/10/2.// Mail:1016427040@qq.com or jasonshaosjj@gmail.com// Copyright © 2016年 邵金杰. All rights reserved.//原创 2016-10-02 23:43:37 · 328 阅读 · 0 评论 -
UVA 1394 And Then There Was One(约瑟夫环变形)
一共有n个数,那么设0~n-1代表这些数的位置,从0开始是为了取模方便,每隔k删掉一个数,那么第一次删掉的是k-1,然后重新排列k -> 0k+1 -> 1k+2 ->2.....k-2 -> n-2把右边的位置设为重新编号后的x从上面的规律中可以看出,目前n-1个人的位置映射到n个人的位置就是(x+k)%n,所以根据这个规律,可以用n-1推出n,用n-2推出n-1,这原创 2016-10-02 23:02:22 · 222 阅读 · 0 评论 -
UVA 1326 Jurssic Remains(位运算)
因为一共有26位字母,所以可以用一个整形数字的第i位代表第i个字母,1就是奇数次,0就是偶数次。//// main.cpp// Richard//// Created by 邵金杰 on 16/10/2.// Mail:1016427040@qq.com or jasonshaosjj@gmail.com// Copyright © 2016年 邵金杰. All rights原创 2016-10-02 18:27:02 · 248 阅读 · 0 评论 -
UVA 10755 Garbage Heap(最大子长方体 可拓展更高维)
//// main.cpp// Richard//// Created by 邵金杰 on 16/10/2.// Mail:1016427040@qq.com or jasonshaosjj@gmail.com// Copyright © 2016年 邵金杰. All rights reserved.//#include#include#include#incl原创 2016-10-02 11:04:53 · 298 阅读 · 0 评论 -
UVA 1382 Distant Galaxy(枚举优化)
如果四条边都枚举,那么时间复杂度O(n),但是只枚举上下两条线,然后根据上下两条线来算出左右两条线,时间复杂度会大大降低。#include#include#include#includeusing namespace std;const int maxn=100+10;struct node{ int x,y; bool operator < (const node &原创 2016-10-02 00:00:36 · 234 阅读 · 0 评论 -
UVA 11795 Mega Man's Mission(状压dp)
一开始用记忆化搜索写的,最后发现存储状态需要用2^16*2^16的空间,果断放弃。#include#include#include#includeusing namespace std;#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define ss(x) scanf("%d",&x)const int maxn=16;int kil原创 2016-10-16 23:55:15 · 248 阅读 · 0 评论 -
UVA 1330 City Game(最大子矩阵)
//// main.cpp// Richard//// Created by 邵金杰 on 16/10/1.// Mail:1016427040@qq.com or jasonshaosjj@gmail.com// Copyright © 2016年 邵金杰. All rights reserved.//#include#include#include#incl原创 2016-10-01 15:12:59 · 252 阅读 · 0 评论 -
UVA 1398 Meteor(扫描线)
这题很明显是扫描线,把流星在相框里的时间的区间整理出来,然后扫描以下线就可以了。//// main.cpp// Richard//// Created by 邵金杰 on 16/10/1.// Mail:1016427040@qq.com or jasonshaosjj@gmail.com// Copyright © 2016年 邵金杰. All rights reser原创 2016-10-01 09:18:18 · 270 阅读 · 0 评论 -
UVA 1335 Beijing Guards(二分+构造)
这题目偶数的结论可以很容易得出来,但是奇数很麻烦,自己想不出来,看的书上的解释,分成两个区间1-r[1],r[1]+1-p,然后第一个位置取左边的区间,接下来就是偶数尽量往左取,奇数尽量往右取,那么最后一个奇数位尽量往右取,只要它的元素全部都是右边的,没取左边的,那就成功了,所以left]n]==0表明当前定义的物品数目是符合要求,继续缩小范围即可,反之扩大范围。//// main.cpp/原创 2016-09-30 21:19:45 · 213 阅读 · 0 评论 -
UVA 1437 String painter(区间dp)
先把A串当成一个空串,然后f[i][j]表示区间[i,j]的一个空串刷成B串最少需要多少个步骤。在转移的过程中,f[i][j]的初值赋f[i][j]=f[i+1][j]+f[i][i],然后从枚举k=i+1开始到r,如果B[i]==B[k],那么f[i][r]=min(f[i][r],f[i+1][k]+f[k+1][r]),因为这样刷会使步骤尽可能的减少。最后再根据s1,求出最少步骤即可原创 2016-10-19 16:04:56 · 399 阅读 · 0 评论 -
UVA 1450 Airport (二分)
这题的难点在于判断哪边飞,如果其中一边为0,那么肯定是不为0的飞,巧妙之处在于如果两边都不为0,那么就留着,一旦两遍超过二分答案的数量超过留着的可以起飞的机数,那么二分答案肯定失败了,重新二分即可。#include#include#include#includeusing namespace std;const int maxn=5000+10;int A[maxn],B[maxn原创 2016-10-06 15:51:40 · 314 阅读 · 0 评论 -
HDU 1701 ACMer
这题意太蛋疼了,要求人数最少,那么x从1枚举,人数最少也就是说ACMer数也是最少。#includeusing namespace std;int main(){ int t; cin>>t; while(t--) { int x=1; double p,q; cin>>p>>q; while((原创 2017-01-24 14:17:27 · 235 阅读 · 0 评论 -
HDU 1215 七夕节(打表)
这题一开始想用唯一分解定理做,蠢哭。#includeusing namespace std;const int maxn=500000+5;int a[maxn];int main(){ for(int i=1;i<maxn;i++){ for(int j=i+i;j<maxn;j+=i){ a[j]+=i; } }原创 2017-01-24 13:27:06 · 347 阅读 · 0 评论 -
HDU 1214 圆桌会议
#includeusing namespace std;int main(){ int n; while(~scanf("%d",&n)) { int ans=(n-n/2)*(n-n/2-1)/2+(n/2-1)*(n/2)/2; printf("%d\n",ans); } return 0;}原创 2017-01-24 12:17:56 · 246 阅读 · 0 评论 -
HDU 1210 Eddy's 洗牌问题(找规律)
#includeusing namespace std;int main(){ int n; while(~scanf("%d",&n)) { int i=2,step=0; while(i!=1) { if(i<=n) i*=2; else i=(i-n-1)*2+1;原创 2017-01-23 20:37:08 · 321 阅读 · 0 评论 -
SPOJ Make them equal !
把所有数加起来,对个数取模,如果刚好等于0,那么都可凑成n各ans/n,如果不等于0,可以凑成n-1个(ans-ans%n)/(n-1)。#includeusing namespace std;const int maxn=100000+5;int a[maxn];int main(){ int t; cin>>t; while(t--) {原创 2016-12-31 20:27:13 · 232 阅读 · 0 评论 -
UVA 11825 Hacker's Crackdown(状压dp)
先把在同一网络中的电脑整理出来,然后再枚举子集,最后就是一般的状压dp。#include#includeusing namespace std;const int maxn=16;int p[1<<maxn],dp[1<<maxn],cover[1<<maxn];int main(){ int n,kase=0; while(scanf("%d",&n)&&n)原创 2016-10-08 19:56:34 · 370 阅读 · 0 评论 -
UVA 1354 Mobile Computing(枚举二叉树+枚举子集)
#include#include#include#include#includeusing namespace std;struct Tree{ double L,R; Tree():L(0),R(0) {}};const int maxn=6;int vis[1<<maxn];vector tree[1<<maxn];double sum[1<<maxn];原创 2016-10-08 18:58:53 · 249 阅读 · 0 评论 -
UVA 1374 Power Calculus(IDA*)
之前用普通dfs做的,然后只看了书上的翻译,没看题目,然后就坑了,这题之前产生的x^y都是可以用的,我一开始做以为只能平方,加一和减一。#includeint max(int a,int b) {return (a>b)?a:b;}int n,a[20];int maxdd=13;bool dfs(int d,int maxd){ if(a[d]==n) return tru原创 2016-10-08 14:10:34 · 217 阅读 · 0 评论 -
UVA 1377 Ruler(dfs)
这题目自己写一直WA,后来发现正确搜索枚举的刻度并不一定是题目中给你的,而可能是两个刻度中间隔的,枚举完整之后答案就会完备而且可能会更优。#include#include#include#include#includeusing namespace std;const int maxn=50+5;int vis[maxn],d[maxn],id[1000000+10],a[maxn]原创 2016-10-08 12:49:36 · 279 阅读 · 0 评论 -
UVA 1467 Installations(贪心)
思路:点击打开链接#include#include#include#includeusing namespace std;const int maxn=1000+10;struct node{ int s,d;}ti[maxn];int n,p;int cmp(node a,node b){ return a.d<b.d;}int deal(int x)原创 2016-10-07 23:12:13 · 268 阅读 · 0 评论 -
UVA 1427 Parade(dp)
这题poj上时限卡得太紧了,IO不优化超市,优化IO313ms。定义状态为f[i][j]代表走到第i行第j个点的最大高兴值,那么f[i][j]可以由两个状态转移过来,f[i][j]=max(f[i+1][k]-sum[i][k]+sum[i][j],f[i+1][k]+sum[i][k]-sum[i][j]),那么只需要计算出左边过来的最大值和右边过来的最大值即可,从上面的式子中可以发现,这是原创 2016-10-20 09:48:55 · 230 阅读 · 0 评论 -
UVA 1422 Processor(优先队列+贪心+二分)
这应该算是个难题,难点在于如何处理判断能否在规定时间完成任务。思路是设的速度当作一个剩余值res,当res为0时,代表现在当前时间的已经没有处理任务能力了,然后枚举结束时间,如果从优先队列从跳出来的node结束时间小于当前枚举的时间,代表着在那个结束时间内,无法处理完成这个任务,直接范围false,如果最后能完成枚举结束时间的for循环,那么只要判断所有任务都处理完了,并且队列里没有元素了,那原创 2016-10-07 20:26:24 · 285 阅读 · 0 评论 -
UVA 1418 WonderTeam(假设)
这题目真是看的云里雾里。#includeusing namespace std;int main(){ int n; while(cin>>n) { if(n==0) break; if(n<=3) cout<<1<<endl; else if(n==4) cout<<2<<endl; else co原创 2016-10-06 20:03:53 · 223 阅读 · 0 评论 -
UVA 1474 Evacuation Plan(dp)
这题一开始状态想对了,但是因为是n^2,所以直接被否定了,但是最后居然看到时间20000ms= =。定义状态f[i][j]代表处理完了前i个队,分配到j个避难处的最短路径和,那么不难想到状态转移是f[i][j]=min(f[i-1][j],f[i-1][j-1])+abs(d[i]-d[j]),f[i][j]只能由两种状态转移过来,处理完i-1个队,分配了j-1个避难处,当处理i时,可能i会被原创 2016-10-19 20:44:49 · 208 阅读 · 0 评论 -
UVA 12105 Bigger is Better(数位dp)
f[i][j]表示用i根棍子余数为j可以组成的最大数。但是最长可能有55位,所以用字符串来保存这个数,所以定义f[i][j][k];每次先枚举火柴棍的根数,再枚举余数,最后枚举最新加进去的数字,每次把火柴棍为i时,余数为0的最大组成数字记下来即可。#include#include#include#includeusing namespace std;char f[105][300原创 2016-10-19 18:08:44 · 219 阅读 · 0 评论 -
UVA 1344 Tian Ji -- The Horse Racing(模拟)
如果tj最慢的马比qw最慢的快,那么这两匹马比,赢。如果tj最快的马比qw最快的快,那么这两匹马比,赢。如果上述两个条件都不成立,那么tj当前最慢的与qw当前最快的比,如果tj当前最慢的比qw当前最快的慢,则输一场,否则平局。#include#include#include#includeusing namespace std;const int maxn=1000+10;原创 2016-10-06 18:17:15 · 393 阅读 · 0 评论 -
UVA 1452 Jump(约瑟夫环变形)
当i=2时,可以求出第二死的,当i=3时,可以求出第三死的,那么只要像第一死的一样递推下去就可以了。#include#include#include#includeusing namespace std;#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define ss(x) scanf("%d",&x)int main(){ in原创 2016-10-16 15:51:24 · 330 阅读 · 0 评论 -
UVA 1366 Martian Mining(dp)
这一题只要选中i,j那么无论是横的,还是列的都是将i,j之前的一排全部选了,不能转弯。所以每次更新相当于从一个已有的一个矩形的长或宽扩展1,那么状态方程就可以定义为dp[i][j]=max(dp[i-1][j]+row[i][j],dp[i][j-1]+col[i][j])。#include#include#include#includeusing namespace std;c原创 2016-10-16 14:25:28 · 216 阅读 · 0 评论 -
UVA 11549 Calculator Conundrum(floyd判圈法+两种速度慢的一般写法)
这题一定会出现循环的,因为如果截取n位数,那么数的范围是从1~10^n,所以如果最坏情况从1~10^n全部跑完,那么肯定会跑到其中一个已经跑过的数,所以一定会循环。速度最慢的 set+stream 2200ms。#include#include#include#include#include#includeusing namespace std;int next(int n,原创 2016-09-30 18:45:36 · 292 阅读 · 0 评论 -
UVA 1392 DNA Regions(单调队列+二分)
(i-j)*p>=(f[i]-f[j])*100==>i*p-f[i]*100>=j*p-f[j]*100,所以只要维护一个单调递减队列,找出最近的j就可以了。第一个元素是0,因为第0个的时候0*p-f[0]*100=0,所以只要i*p-f[i]*100大于0,那么肯定是可行的。#include#include#include#include#includeusing namespa原创 2016-10-14 19:08:59 · 251 阅读 · 0 评论 -
UVA 2995 Image is Everying(模拟)
主要是转到三维上进行模拟,然后两个侧面配对,如果失败,那么减去这个单位立方体,继续检查,知道没有配对失败为止。//// main.cpp// Richard//// Created by 邵金杰 on 16/9/28.// Copyright © 2016年 邵金杰. All rights reserved.//#include#include#include#i原创 2016-09-28 23:16:44 · 201 阅读 · 0 评论