- 博客(72)
- 收藏
- 关注
原创 Codeforces Round #297 (Div. 2) E Anya and Cubes
原理链接:http://codeforces.com/contest/525/problem/E题意:给了n个立方块,上面都有一个数字,然后有k个感叹号,你可以选择放在一个立方块上,之后形成阶乘。问选择一些立方块然后有的贴上感叹号最后和为S的方案数量。思路:刚开始想dp。。然后每个方块3种决策,然后用记忆化,不过由于S太大,3^25状态可以全部存在,然后就T了。。后来一看n为25,可以
2015-03-28 09:28:05 363
原创 Codeforces Round #297 (Div. 2) D Arthur and Walls
原题链接:http://codeforces.com/contest/525/problem/D题意:给了一个矩阵,里面有墙('*')和空地('.'),然后所有空地(边相邻的)都要是矩形思路:一开始想的是搜索每个点最远的地方,然后果断T了,因为如果后来搜索的矩形包含前面的矩形的话,一个点可以被访问多次,有很多回溯。然后看了题解。。有个神奇的现象,我们可以观察2*2的方格,如果只有一个'
2015-03-28 09:18:44 376
原创 uva 672 Gangsters
题意:就是有N个人,有一个P值和一个S值,然后商店有一个K值,当这个人来的时候如果K和S相等,则进去,则总P加上该人的P值,每秒K可以+1或者-1或者不变。思路:先按时间排序。d[i]表示第i个人进来总P值最大是多少。则d[i] = max(d[j], d[j]+p[i]) (t[i]-t[j] >= abs(S[i]-S[j])) ,这里要注意的就是初始化一开始所有人设为-1,d[0]=0;
2015-01-29 21:09:31 411
原创 uva 1351 String Compression(dp)
题意:给一个字符串,如果其中有m个子串s0相等的话,可以表示为m(s0),然后问给定字符串最少可以表示成多少?思路:设d[i][j]为i~j字符串最小长度是多少。则d[i][j] = min{d[i][k]+d[k][j]},还要考虑自身存在循环的子串,则枚举s0的长度,d[i][j] = min(d[i][j],d[i][i+k-1] + 2 + cal(j-i+1)/k);#inclu
2015-01-29 21:01:38 372
原创 uva 10163 Storage Keepers
题意:有N个仓库,让M个人守,使每个仓库安全值尽量高的同时,花费最小。思路:如果两个一起更新的话,当安全值相等,更细花费,或者安全值更大,一起更新,这样会导致问题就是,因为题目安全值是所有值中的最小值,有可能前面其实取更下花费的人就能达到最小值,但是你前面已经更新成了较大的。所以应该分两步,第一步,先求出能够使仓库达到的最大值,第二步,求出使每个仓库达到这个值的最小花费。第一个状态表示
2015-01-29 20:53:30 351
原创 uva 11404 Palindromic Subsequence
题意:求最长回文子序列,并且是最小子序列。思路:求最长回文子序列可以将序列倒过来求一遍LCS,而这里要求字典序最小,可以开一个结构体同时更新字典序,不过求出来的并不一定是回文子序列。比如:bcbacbccbcabcb求出来LCS字典序最小显然是bcabc,并不是回文的。则这里考虑一半最优解求出另一半,则必然是回文的,注意考虑奇偶。思路2:看别人代码,还有种思路,用d[i
2015-01-27 11:55:18 399
原创 uva 11552 Fewest Flops
题意:把一个字符串每k个分成一组,组内可以任意排列,然后相同字母在一起为一块,最少多少块。思路:组内必然是一起的排一起,不用考虑,然后我们用d[i][v]表示第i块用v做最后一个字符有多少块。用vis[i][v]表示第i块是否存在vd[i][v] = min{d[i-1][v1] + len(i) - vis[i][v1]},如果有前一块v1转移过来的时候,且第i块也存在v1则,可以减
2015-01-27 11:47:13 338
原创 uva 1099 Sharing Chocolate
题意:给定一个面积的巧克力,能否分解成n个给定面积的巧克力。思路:记忆话搜索,d[r][S]表示r行,面积为S(用集合表示),是否可行,注意每次搜索的时候保证可以整除,因为需要根据面积来算出列的大小。#include#include#include#define mem(name,value) memset(name,value,sizeof(name))#define FOR(i
2015-01-27 11:35:19 426
原创 uva 1169 Robotruck (dp)
令d[i] 为从原点出发,将前i个垃圾清理完存放垃圾桶的最小距离。则d[i] = min{ d[j] + dist0[j+1] + dist(j+1,i) + dist0(i) | j而我们令sumd(i) 为从0走到i的距离之和,则dist(j+1,i) 为 sumd(i) - sumd(j+1);则d[i] = min{ d[j] + dist0[j+1] - sumd(j+1)
2015-01-27 10:55:00 441
原创 uva 11825 Hackers' Crackdown 集合上的dp
题意:有n台计算机n个服务,每个计算机有相关联的计算机,攻击之后,相关联的也受影响。我们只能让某一个计算机停止某一个服务,如何使尽量多的服务完全瘫痪(没有任何计算机有该服务)就是有n个集合P1,P2....Pn,每个集合表示的与之相关联的计算机,分成尽量多的一组,使并集为全集(这样这些计算机停止一项服务就行)
2015-01-20 11:42:14 326
原创 uva 10891 Game of Sum 区间dp
题意:有一个长度为n的整数序列,A和B轮流取左端或者右端部分,使自己得分高。整数序列的值是一定的,所以使一个人得分越高,即是另一个人的得分越低。d(i,j)表示原序列i~j个,则d(i,j) = sum(i,j) - min{d(i+1,j),d(i+2,j)....d(j,j),d(i,j-1)...d(i,i), 0},0 表示全部取完,若直接记忆化搜索的话,O(n^3),若用递推,可以用
2015-01-20 11:30:25 321
原创 uva 10635 Prince and Princess LIS
题意:有两个长度为p+1,和q+1的序列,第一个都为1,且元素都不相同,求最长公共子序列。想法:总序列长度可以达到250^2,不能用O(pq)的方法求LCS,而发现所有元素都不相同,则可以将A重新编号为1,2,3,4 ……,然后将B映射,求LIS即可,A中不存在的在B中映射为0,可以直接求LIS,因为元素均不相同,而且第一个肯定是最小的为1,即便0后面更新,也只能更新长度为1的最小值。#i
2015-01-20 11:11:50 347
原创 uva 1394 And Then There Was One 递推
题意:格k个人删除一个,第一个删除的是第m个。先不考虑m,按1到n编号,假设删除的是第k-1个,(数k个)则序列 1、2、…… k-1、k、k+1……n-1、n。之后1、2、……k-1、k+1……n。然后从k+1开始重新编号,则成为n+1-k、n+2-k、……n-1、1……n-k。倒着推的话,若知道在n-1次删除的为 f(n-1),则第n次应为 (f(n-1)+k)%n;第
2015-01-20 11:03:36 370 1
原创 Codeforces 453C Little Pony and Summer Sun Celebration 树上dfs
题目比较长。题意大概是,模拟
2014-08-09 21:14:31 404
原创 codeforces 453 B Little Pony and Harmony Chest (状压dp)
题意:求一个b数组,b数组中的所有数互质,和a数组对应下标的数的差的绝对值最小。考虑a数组中的所有数范围为[1,30]则,b数组取值只有可能为[1,59),因为如果取到59及其以后,肯定可以取1,59-30=30-1;而且1可以取多次,1与任何数互质。然后首先需要把[2,59)之间的素数取出来,总共16个。然后状压,1代表那一位的素数因子是否存在。d[i][s][0]表示递推到第i个位
2014-08-05 16:17:43 666
原创 uva 10817 Headmaster's Headache 集合上的dp 位运算
集合上的dp,用到了很多位运算的题目~ 给出s个课程,m个教师,n个求职者,教师必须招聘,然后招聘一些求职者,使得每一门课都至少有两个老师能教。问题就转换成了招聘哪些求职者使得花费最少。因为s范围小于8,则可以用二进制表示,用集合s1表示恰好有一个人教的课的集合,用集合s2表示有两个人教的课的集合,则每次状态转移即为选择这名求职者还是不选(教师必须选)具体看代码。 d(i,s1,s
2014-07-21 22:40:19 579
原创 uva 1252 Twenty Questions 状压dp
集合上的dp,看小紫书想了好久~有n个物体,m个特征,最少询问多少次能保证猜到是哪个问题。首先在读入的时候将每个物体转化为一个二进制整数,用一个集合s来表示已经询问了哪些特征。用d(s,a)来表示询问了集合s的特征,有集合a个特征已经具备,还需要问多少个特征的最小值。a一定为s的子集。则状态方程为 d(s,a) = min{ max(d(s+{k},a+{k}),(s+{k},a
2014-07-21 22:15:46 628
原创 题目汇总
记录做题的历史……把做过的题目类型汇总下,时时更新~,写了题解会把链接贴上面的搜索:lightoj :1046,最小生成树:uva:10034, lightoj: 1029,最短路:hdu:1874,2544,3790 poj: 2387,2421,1502,2253,1062 lightoj:1002
2014-03-21 17:59:45 521
原创 uva 10905 - Children's Game
贪心。给你n个数字让你输出他们合起来的最大数字,任意排列。就是让尽可能让每一位都最大。比如9和90应该让9排在前面。用STL和重载。不过重载的cmp注意不能写成如果两个数前面相等,然后比较那个长的数后面和那个短的数。如:A1A2A3A4A5A6B1B2B3B4B1B2B3B4A1A2A3A4A5A6我刚开始做,比较完前4个之后,然后用A5和B1(即又重复比B)直到比完A
2014-03-06 18:01:58 471
原创 uva 550 - Multiplying by Rotation
给出三个数,第一个数为几进制情况下,第二个数为最后一个数,第三个数为乘数求出最少要多少位的数才能够使最后一个数变为前一个数。即数a就是把数b的最后一位移到了最前面模拟乘法这个过程即可。#includeint main(){ //freopen("in.txt","r",stdin); int a,b,c,i; while(~scanf("%d%d%d",
2014-03-06 17:45:29 455
原创 uva 11205 - The broken pedometer
二进制枚举。暴力的好题,巧用二进制去枚举。就是求出最少需要多少位可以表示出这些数字并区分,(就是取最少的位数使每一个串数字还是不同)然后我们把最大范围内每一个二进制的数枚举出来,然后判断最少几位能使上面的01串无重复的表达。将输入的一串01串用存入一个数中,用二进制看的话就是101010之类的。具体看代码:#include#includeconst int MAXN=110
2014-03-05 16:00:09 902
原创 uva 10935 - Throwing cards away I
队列的一道题,题目就是给定1到n个数字,每次从最前面丢一个,然后把下一个放到最后面,直到只剩下一个。#include#includeusing namespace std;int main(){ // freopen("in.txt","r",stdin); queueq; int n; while(~scanf("%d",&n)){ if
2014-03-05 15:43:46 597
原创 uva 10474 - Where is the Marble
就是找一个数字n在前面给的m个数中是第几大的。如果有一样的话,取第一次出现的。数据量很小,直接排序,然后二分查找即可。不过如果是10^7的数据量,则不能直接排序然后查找。手写快速排序查看划分区域和要查找的数的大小,然后只进行一边的递归即可。(这题不用这样)#include#include#includeusing namespace std;const int MAXN
2014-03-05 15:39:24 440
原创 uva 10361 - Automatic Poetry
字符串操作的。将两个#include#includeconst int MAXN=100+10;int main(){ //freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int T; char a[MAXN],b[2][MAXN],c[2][MAXN]; scanf(
2014-03-05 15:29:14 438
原创 uva 10167 - Birthday Cake
就是让樱桃在你切一刀的两边均匀分布,注意半径不超过100;还注意不能再切的那条线上。#include#includeconst int MAXN=110;int N;int beeline[2][MAXN];bool ok(int A,int B){ int counter=0,i; for(i=0;i<2*N;i++){ int temp=A*b
2014-03-05 15:25:24 508
原创 uva 10161 - Ant on a Chessboard
观察奇数的平方在第一列上,偶数的平方在第一行上交替。#include#includeint main(){ //freopen("in.txt","r",stdin); int a; while(scanf("%d",&a)!=EOF){ if(a==0) break; int b=sqrt(a); int temp
2014-03-05 15:22:55 429
原创 uva 10152 - ShellSort
名字叫希尔排序,不过好像没什么关系~。给你一堆龟壳,龟壳上面有一字符串,然后再给定指定顺序的龟壳,用最少的操作次数达到这个顺序,每次操作只能将一个龟壳抽出,放到最上面。将原来的顺序和指定顺序从下往上比较,若原来顺序的字符串在指定顺序的字符串上面则匹配,就是抽出别的时候会自动掉下来了,最后按照未匹配的指定字符串输出即可。#include#include#include#includ
2014-03-05 15:16:41 452
原创 uva 10129 - Play on Words
欧拉回路的一道不错的题目。(顺便总结下欧拉回路)欧拉道路:能从无向图中的一个结点出发走出一条道路,每条边恰好经过一次。如果一个无向图是连通的,且最多只有两个奇点(点的度数为奇数的点),则一定存在欧拉道路。如果有两个奇点,则必须从其中一个奇点出发,另一个奇点终止;如果奇点不存在,则可以从任意点出发,最终一定会回到该点。(称为欧拉回路)。奇点不可能为奇数,一条边提供两个度,起点,终
2014-03-04 19:54:52 695 1
原创 uva 10110 - Light, more light
判断最后一盏灯,而一个数因式分解,必为两个不同数相乘,(除非完全平方数),则必为一开一关。只用判断最后一个数是否为完全平方数即可。注意2^32已经爆int。。。这原因WA了好多次。 #include#include#define ll long longint main(){ // freopen("in.txt","r",stdin); ll i,m;
2014-03-04 19:15:50 425
原创 uva 10098 - Generating Fast
全排列,就是给一个字符串,输出全排列。。用next_permutation水过了。。#include#include#includeusing namespace std;const int MAXN=15;char a[MAXN];int main(){ // freopen("in.txt","r",stdin); int T; scanf("%d",
2014-03-04 19:09:56 429
原创 uva 10082 - WERTYU
水题。。注意\表示应该为'\\'。#include#includeint main(){ //freopen("in.txt","r",stdin); int i; char c; char *a="`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./}"; while(scanf("%c",&c)!=E
2014-03-04 19:07:38 420
原创 uva 10035 - Primary Arithmetic
水题。求两个数相加进了多少次位,模拟加法过程即可。#includeint main(){ //freopen("in.txt","r",stdin); int a,b; while(~scanf("%d%d",&a,&b)){ if(!a && !b) break; int temp1=0,temp2=0,sum=0,counter=
2014-03-04 19:06:15 459
原创 uva 10025 - The 1 2 ... n = k problem
就是给出一个数,最少能用多少个数表示。每个数前面为正号或者负号。可以只考虑正数(输入的负数当正数也行。算出正数的符号全变就行,数字不会改变);先把前n项和的值存入数组,直到大于1e9,题目给的最大值。然后判断所给的数字在前k与k+1项的和之间,然后判断与小的那个差,若为奇数,则最少数+1,直到为偶数。因为每次将一个负号变成正号的时候,是减去两倍的这个数,必为偶数。还有,注意
2014-03-04 19:01:31 486
原创 uva 784 - Maze Exploration
图的dfs水题。就是从一个点开始,看可以给哪些地方涂色。直接深搜即可。#include#includeconst int MAXN=100;char a[35][MAXN];int dx[]={-1,0,0,1};int dy[]={0,1,-1,0};void dfs(int x,int y){ a[x][y]='#'; for(int i=0;i<4;i
2014-03-03 19:02:07 492
原创 uva 729 - The Hamming Distance Problem
题意大概就是给出01串,让你输出全排列。可以用next_permutation水过。用dfs的时候注意添加0或者1的时候判断是否重复和注意不要重复递归。#include#includeconst int MAXN=20;int P[MAXN],A[MAXN];void dfs(int cur,int n){ if(cur==n){ for(int i=0
2014-03-03 18:59:39 478
原创 uva 705 - Slash Maze
图。就是求'/'和'\'能构成多少个封闭图形,和最大的封闭图形的面积是多少。可以把图扩大两倍或者三倍。如果扩大两倍dfs的时候考虑太多,不好理解。我扩大了三倍。即一个格子被分为九个格子,若为'\'则将正对角线的三个标记为不能走, 若为'/'则将副对角线的标记,然后用dfs遍历图。注意最后求出的面积要除以三,#include#includeconst int MAXN
2014-03-03 18:52:11 476
原创 uva 699 - The Falling Leaves
数据结构,树。求每列各结点的合,左子树往左边多一列,右子树往右边。看题目中的图很容易理解。。注意,有可能亮点会重合。还有输入有换行。一开始没看懂样例可以建树做,不过我觉得太麻烦了直接将开个大点的数组,中间那个数字存根结点的,然后若往左,则坐标减减,往右则加。#include#include#includeconst int MAXN=2000;int v[MAXN],mid
2014-03-02 21:48:31 547
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人