随笔分类 - ACM题解
摘要:题目链接题目大意,给定一个整数表达式A1/A2/A3/.../An,('/'为除号1<=n<=10000,1<=Ai<=1000000000),问是否能通过添加括号使得表达式的值为整数。咋一看似乎没思路,但仔细想,不难发现这里存在最优策略,最优策略是用一个括号将表达式变成A1/(A2/A3/.../An)。证明如下:n为1时,直接输出"YES",n大于1时,首先,A2一定为分母,无论如何添加括号都无法改变这个事实,其次,按照上面的策略加括号后,只有A2为分母,所以这是个最优策略。有了最优策略后,我们需要做的就是不断约分(求最大公约数)
阅读全文
摘要:最基础的最小生成树,简单题。View Code 1 #include <stdio.h> 2 #include <math.h> 3 #include <stdlib.h> 4 #define D(x1,y1,x2,y2) (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))) 5 #define N 100 6 #define M 5000 7 struct node 8 { 9 int a,b;10 double d;11 }edge[M];12 int n,m;13 double x[N],y[N];14 int p[M];15
阅读全文
摘要:用floyd求最短路,难得的一次ACView Code 1 #include <stdio.h> 2 #define MIN(a,b) ((a)<(b)?(a):(b)) 3 #define N 20 4 #define INF 0x7fffff 5 int dist[N][N]; 6 int main() 7 { 8 int i,j,k,x,kase=0; 9 while(1)10 {11 for(i=0;i<N;i++)12 for(j=i+1;j<N;j++) dist[i][j]=dist[j][i]=INF;13...
阅读全文
摘要:题目链接题目大意是给定一个有向图,求最少需添加多少条有向边使得原图强连通。可以先求强连通分量,统计缩点后的图中入度为0的点和出度为0的点,答案就是两者中的较大者,需要注意的是当原图是强连通时,直接输出0。因为没有初始化WA了一次。#include <stdio.h>#include <string.h>#define CLR(a) (memset(a,0,sizeof(a)))#define N 100char g[N][N],vis[N];int n;int ord[N],id[N],cnt,din[N],dout[N];void dfs(int u){ int v;
阅读全文
摘要:题目链接由于之前没写过网络流方面的题目,所以第一次写的时候居然想到用动态规划去做(在没有环的情况下貌似可以,有环会RE)。现在看来,这题是个求最小割的题,因为最大流量最小割相等,所以也就是求最大流量。容量网络也很明显。我用的是标号法(Edmonds-Karp算法)。#include <stdio.h>#include <string.h>#define N 152#define INF 0x7fffffff#define MIN(a,b) ((a)<(b)?(a):(b))int c[N][N],flow[N][N],a[N],p[N],f,n,m;int que
阅读全文
摘要:题目链接并查集的题。一开始的时候没看懂题,以为要用最短路算法去做,结果样例都没过,后在队友的指导下终于理解了题意。用并查集写好后,第一次提交莫名奇妙的RE,检查后发现查函数没写返回值(编译器没提示呢?而且样例也过了),第二次提交是WA,经检查后发现是无穷大设得不够大。下次一定要注意这些细节问题。#include <stdio.h>#define N 10005#define INF 0x7fffffffint p[N],d[N],out[N],n;void make_set(){ int i; for(i=0;i<=n;i++) p[i]=i,d[i]=0,out[i]=0;
阅读全文
摘要:题目链接动态规划题,LCS的变形。无语了,写错两个字母,WA了3次啊!#include <stdio.h>#include <string.h>#define MAX(a,b) ((a)>(b)?(a):(b))#define N 105int m[5][5]={ 5,-1,-2,-1,-3, -1,5,-3,-2,-4, -2,-3,5,-2,-2, -1,-2,-2,5,-1, -3,-4,-2,-1,-10000};char a[N],b[N],vis[N][N],la,lb;int c[N][N];int f(int x,int y){ int i,...
阅读全文
摘要:题目链接题目大意,给定一个字符串,求至少需插入多少字符使其变成回文。动态规划题。#include <stdio.h>#include <memory.h>#include <string.h> #define MIN(a,b) ((a)<(b)?(a):(b)) #define N 5001 char s[N]; int c[N]; int main() { int i,j,n,a,b; while(scanf("%d",&n)!=EOF){ getchar(); gets(s); for(i=n-2;i>=0;i--
阅读全文
摘要:题目链接题目的模型为给定含m个数的数列,将其分为连续的n段,使每段的和的最大值最小(刘汝佳白书上有)。由于是连续的,题目就简单了,之前就是没注意到这点,想了好久都没思路。我们可以首先可以确定结果的上界和下界,然后使用二分法将这个区间不断缩小,这个过程中要判断对于一个给定的x,是否能够在x天内修完路,因为路段是连续的,所以可以使用贪心来判断,贪心策略为,从第一个数开始,将尽量多的数分配到第一段,以此类推,直至分配完成,若分配的段数大于n则无法在x天内完成,否则可以。 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)
阅读全文
摘要:题目链接经典DP问题。由于最初if(c[i][j]>=0) return c[i][j];一句中少写一个等于号造成TLE,查了好久啊……View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 300 5 char a[N],b[N]; 6 int c[N][N]; 7 int f(int i,int j) 8 { 9 if(i<0 || j<0) return 0;10 if(c[i][j]>=
阅读全文
摘要:题目链接简单DP题。View Code 1 #include <stdio.h> 2 #define N 45 3 int c[N][2]; 4 int main() 5 { 6 int t,i,n; 7 c[1][0]=c[1][1]=1; 8 for(i=2;i<N;i++) 9 {10 c[i][0]=c[i-1][0]+c[i-1][1];11 c[i][1]=c[i-1][0];12 }13 scanf("%d",&t);14 for(i=1;i<=t;i++)15 {16 ...
阅读全文
摘要:题目链接简单动态规划题。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define N 500002 4 #define MAX 10000000 5 char vis[MAX]; 6 int c[N]; 7 int main() 8 { 9 int n,i,tmp; 10 c[0]=0,vis[0]=1; 11 for(i=1; i<N; i++) 12 { 13 tmp=c[i-1]-i; 14 if(tmp>0&&!vis[tmp]) vis[tmp]=1,c[i]=tm
阅读全文
摘要:题目链接简单的动态规划题,WA了4次居然是因为N太小,为自己的吝啬感到无语。View Code 1 #include <stdio.h> 2 #define N 21 3 int f[N][N][N]; 4 int w(int a,int b,int c) 5 { 6 if(a<=0 || b<=0 || c<=0) return 1; 7 if(a>20 || b>20 || c>20) return w(20,20,20); 8 if(f[a][b][c]>0) return f[a][b][c]; 9 if(a<b&&a
阅读全文
摘要:题目链接经典的动态规划题(数塔)。View Code 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)) 3 #define N 100 4 int a[N][N],f[N]; 5 int main() 6 { 7 int n,i,j; 8 while(scanf("%d",&n)!=EOF) 9 {10 for(i=0;i<n-1;i++)11 {12 for(j=0;j<i+1;j++) scanf("%d",&a[i][j]);13 ...
阅读全文
摘要:题目链接此题初看起来是一个二分匹配的问题,一个国王有n个儿子,将要与n个女孩结婚,已知每个儿子喜欢某几个女孩,并给出了一个初始匹配,问题是求每个儿子可能与哪些他喜欢的女孩结婚,一旦他选一个结婚后,其他的儿子仍能选到自己喜欢的人结婚。若直接枚举个中可能,然后用匈牙利算法求完美匹配判断,这样的话时间复杂度是O(n5),毫无疑问会超时。在这里,题目给出里一个初始完美匹配,必须加以利用。我们可以把初始完美匹配中的每一对看成结点进行构图,因此每个结点包含一个男孩和一个女孩,若结点i中的男孩喜欢结点j中的女孩,就在结点i与结点j之间连一条有向边,这样问题就转化为求强分图,每个男孩可以与他喜欢的并且与他在同
阅读全文
摘要:题目链接动态规划题。模型为给定一条直线上的n个整点坐标,在其中选取p个点作为警亭,使得其余的点到最近的警亭的距离之和最小(下面简称最小距离和)。对输入坐标排序后,用c[i][j]保存最后一个警亭设在第i点,且该点之前还有j个警亭的情况下,第一点到第i点的最小距离和。照此不难写出状态转移方程。c[i][j]=max{c[k][j-1]+(min(d[i]-d[t],d[t]-d[k]),t=k+1...i-1),k=j-1...i-1}View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <s
阅读全文
摘要:POJ3177POJ3352把这两个题写到一起,是因为这两题完全一样,用下面的代码两个题都可以AC。题目大意是给一个无向连通图,求添加最少边数使原图变成双连通图。由于是第一次写双连通图的缩点,所以WA了5次,在WA到AC的过程中,发现的错误如下:1、深度优先数没有初始化;2、深度优先数初始化错误;3、桥的判断有误;4、输入数据有重边,使用邻接表存储没有跳过重边。下面写一下这题的主要思路,用数组dfn保存各个结点的访问顺序(深度优先数),数组low[k]保存结点k及其子结点通过回边能到达的所有结点的最小深度优先数(下面简称最小深度优先数)。若子节点的最小深度优先数大于父结点的最小深度优先数,则连
阅读全文
摘要:题目链接简单的搜索题,深搜即可。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define CLR(a) (memset(a,0,sizeof(a))) 5 #define N 101 6 char g[N][N]; 7 int n,m,k,ans,tmp; 8 int dir[4][2]={1,0,0,1,-1,0,0,-1}; 9 void dfs(int i,int j)10 {11 int d,ni,nj;12 g[i
阅读全文
摘要:题目链接动态规划题,题目大意,有n个城市,一个人从第一个出发,每天可以选择继续呆在当前城市或者转移到其他城市(可以把继续呆在当前城市看成从当前城市转移到当前城市),第i天呆在第j个城市的收入为in[i][j],从第i个城市转移到第j个城市的费用out[i][j],求m天后的最大收入。把第k天的收入与第k-1天的收入联系起来即可写出状态转移方程。用c[i][j]保存i天过后最后呆在城市j的总收入,c[i][j]=MAX(c[i-1][k]+in[i][j]-out[k][j],k=0,1,...n-1),注意到从第一个城市出发,所以边界为第一天结束时的收入。View Code 1 #inclu.
阅读全文
摘要:题目链接题目的本质就是求最长不下降子序列,这是动态规划的典型,很容易写出O(n2)的算法,但由于MAX=40000,普通算法会超时,必须采用更快的算法。下面简单介绍求最长不下降子序列(可推广到其他类型)的O(nlogn)算法。假设数字序列为a[N](也可不用保存,一边读入一边处理),先介绍如何求以第一个元素开头的最长不下降子序列,我们会用到一个数组d[N],d[k]保存的是数组a中以第一个元素开头的所有长为k的不下降子序列最后一个元素的最小值(下面将简称为最小最后元素),显然d的长度len即为所求。而且容易用反证法证明这个数组是递增的,若存在i<j,且d[i]>d[j],可以这样想
阅读全文

浙公网安备 33010602011771号