摘要:
LA_4254 一般最大值最小的问题都可以通过二分来求解,这个题目也不例外。我们对处理器速度进行二分之后,问题就转化成了对于给定的处理速度,问处理器是否可以将这些问题处理完。一个贪心的思路就是每个时刻应该尽量做可以做的任务中,结束时间最早的那个,这样最起码不会使结果更糟。这样就可以枚举每个单位时间,然后去找可以做的并且结束时间最早的那个去做,直到用完这一单位时间或者无任务可做为止。最后如果发现哪个任务还没做完,就说明在这个给定的处理速度下,处理器是不能完成所有任务的。 在查找结束时间最早的可做的任务的过程中,我的代码借助了线段树。不过据AC排名来看,应该还有更简便的算法,只不过我暂时没有想到。 阅读全文
摘要:
UVA_10905 我们不妨先定义一个大于号“》”:对于字符串a,b,如果有a》b就表示ab的字典序要大于ba的字典序。 假设:如果有a》b,且b》c,那么就有a》c。 如果这个假设满足,那么N个字符串就可以按》的关系排成一排,这时拼成的字符串就是字典序最大的(同时也是值最大的,因为最终拼成的字符串的长度是一定的,所以值的大小关系和字典序的大小关系是相同的)。 下面用反证法证明为什么这样拼成的字符串的字典序一定是最大的:如果最终拼成的字符串不是这样的,那么就一定存在相邻的两个字符串a、b不满足a》b,那么我们可以交换a、b的顺序,这样得到的结果不会变得更差。于是我们不停的交换不满足a》b的两个 阅读全文
摘要:
UVA_10382 喷水装置能否覆盖草坪,其实只取决于图中每个圆蓝色部分能否将草坪覆盖,这样我们就将问题转化成了有若干线段,求覆盖一个指定区间最少要多少条线段。#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#define MAXN 10010const double eps = 1e-10;int N, M;double L, W;struct Seg{ double x, y; bool operator < (const Seg &t) 阅读全文
摘要:
UVA_10340 我们不妨从左至右依次生成字符串s,这样我们只要依次扫描t,如果当前字符和s中待生成的字符一样,就拿出来生成即可,这样可以保证每个所需字符在t中拿出时的位置都是尽可能靠左的,这样和拿出一个更靠右一点的相同的字符相比,所得到的结果至少不会更差。#include<stdio.h>#include<string.h>#define MAXL 1000010char s[MAXL], t[MAXL];int process(){ int i = 0; for(int j = 0; t[j]; j ++) if(s[i] == t[j]) ++ i; r... 阅读全文
摘要:
UVA_10970 假设上面就是我们要切的巧克力,橙色的边表示切痕,而且是只有橙色边的位置才会有切痕,如果每条短边都视作一刀的话,那么上面那个巧克力显然要切17刀,这也是最坏的情况了,那么刀数为什么可以比17刀少呢?我们不妨观察红点的位置,如果左右刀痕连在了一起那么可以少一刀,同理如果上下刀痕连一起,也可以少一刀,但是上下和左右的刀痕不能同时连一起。那么也就是说如果有一个红色的这样的点,那么就可以使上下刀痕连一起,或者左右刀痕连一起,从而减少一刀,那么一共有6个这样的点,就可以减少6刀,所以最优就是11刀。 (我的程序是先假设横着切了N-1刀,然后再竖着切(M - 1) * N刀。)#incl 阅读全文
摘要:
LA_3602 由于每一位都是独立的,我们依次处理每一位即可。对每一位找到出现次数最多的字符,如果次数相同的话,就找字典序较小的那个。#include<stdio.h>#include<string.h>#include<iostream>#define MAXN 60#define MAXL 1010int N, L;char a[MAXN][MAXL], id[128], ch[4] = {'A', 'C', 'G', 'T'};void input(){ scanf("%d%d& 阅读全文
摘要:
LA_3213 题目的大意是将第二个字符串中的每个字符先做一个一一映射,然后再将各个字符打乱(也就是选择性地变换一下位置),问能否变成第一个字符串。 这个问题中有一个守恒量,就是各类字符的数量,比如一开始各类字符的数量分别为1、2、2、3的话,那么无论怎么变换,最后各类字符的数量一定还是1、2、2、3,只不过之前有3个的可能是A,而现在变成了有3个的是B,或者Y,或者其他的字符等等。而且,如果各类字符在数量上能够一一对应的话,那么一定可以通过某种手段将第二个字符串变成第一个字符串,所以我们只需判断各类字符的数量上能否一一对应。#include<stdio.h>#include< 阅读全文
摘要:
UVA_11039 假设当前要放一个blue的floor,那么这个floor的size应当是越大越好的,因为这样做相比于选一个size较小的,至少不会使结果变得更糟。于是接下来的工作只要枚举最下面是放的blue的或者red的,然后向上依次选择颜色交替的、size尽量大的floor即可。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXN 500010int N, a[MAXN];bool cmp(int x, int y){ return std::abs(x) < std 阅读全文
摘要:
UVA_11636 一个贪心策略就是当前有多少行就全部进行复制,这样才可能得到更多的行。于是行数的变化就会是1,2,4,...,2^i,...,直到剩下的行比已有行要少为止,再复制一次就可以达到要求了(如果剩余的行数为0,当然就不要再复制了)。#include<stdio.h>#include<string.h>int main(){ int N, t = 0; while(scanf("%d", &N), N > 0) { int i; for(i = 16; (N & 1 << i) == 0; i --); p 阅读全文
摘要:
/* dp[i][j]表示递推到i时,swap的次数为j时的方案数。 i要么单独形成1个循环节,这时不增加swap的次数,要么放到前i-1个数某个数的后面,从而插入到某个循环中,这样swap的次数会+1。 */#include<stdio.h>#include<string.h>typedef unsigned long long LL;int N, K;LL dp[25][25];void prep(){ memset(dp, 0, sizeof(dp)); dp[0][0] = 1; for(int i = 1; i <= 21; i ++) f... 阅读全文