摘要: 这道题跟最长上升子序列查不多,只不过需要记录的信息不一样关于最长上升子序列见:最长上升子序列nlogn算法 题目传送门 1 #include<stdio.h> 2 #include<string.h> 3 int a[1001]; 4 int b[1001]; 5 int main() 6 { 7 int n,i,j; 8 int max; 9 while(scanf("%d",&n),n)10 {11 memset(b,0,sizeof(b));12 memset(a,0,sizeof(a));13 for(i... 阅读全文
posted @ 2013-05-10 16:42 飞向梦 阅读(158) 评论(0) 推荐(0) 编辑
摘要: 这题目是经典的DP题目,也可叫作LIS(Longest Increasing Subsequence)最长上升子序列 或者 最长不下降子序列。很基础的题目,有两种算法,复杂度分别为O(n*logn)和O(n^2) 。A.O(n^2)算法分析如下: (a[1]...a[n] 存的都是输入的数) 1、对于a[n]来说,由于它是最后一个数,所以当从a[n]开始查找时,只存在长度为1的不下降子序列;2、若从a[n-1]开始查找,则存在下面的两种可能性: (1)若a[n-1] < a[n] 则存在长度为2的不下降子序列 a[n-1],a[n]; (2)若a[n-1] > a[n] 则存在长度 阅读全文
posted @ 2013-05-10 16:32 飞向梦 阅读(486) 评论(0) 推荐(0) 编辑
摘要: 这个题目比较简单,主要是考虑输出空格回车思路:找公差——2*m,每次加上2*m 1 #include<stdio.h> 2 int main() 3 { 4 int m,n,i,k; 5 while(scanf("%d%d",&n,&m)==2) 6 { 7 k = n/m; 8 for(i=0;i<n/m;i++) 9 {10 if(i==0)printf("%d",m+1);11 else12 printf(" %d",m+1+m*2*i)... 阅读全文
posted @ 2013-05-10 16:05 飞向梦 阅读(150) 评论(0) 推荐(0) 编辑
摘要: 这个题目第一眼看了真没思路,也没想到跟动态规划有关系,最后还是看了Tanky Woo的文章才明白看图片对比一下,数轴以5为塔顶,左右两边依次往下落,就形成数塔 题目传送门 1 #include<stdio.h> 2 #include<string.h> 3 int dp[11][100001]; 4 int max(int a, int b) 5 { 6 return a>b?a:b; 7 } 8 9 int main()10 {11 int n,x,t,maxtime;12 int i,j;13 while(scanf("%d",&n 阅读全文
posted @ 2013-05-10 15:07 飞向梦 阅读(107) 评论(0) 推荐(0) 编辑
摘要: 动态规划经典题目充分体现了动态规划的核心思想——自顶先下分析,自底向上计算借用课件里面的话:1、从顶点出发时到底向左走还是向右走应取决于是从左走能取到最大值还是从右走能取到最大值,只要左右两道路径上的最大值求出来了才能作出决策。2、同样,下一层的走向又要取决于再下一层上的最大值是否已经求出才能决策。这样一层一层推下去,直到倒数第二层时就非常明了。 题目传送门 1 #include<stdio.h> 2 int a[101][101]; 3 int max(int a, int b) 4 { 5 return a>b?a:b; 6 } 7 int main() 8 { 9 in 阅读全文
posted @ 2013-05-10 14:59 飞向梦 阅读(109) 评论(0) 推荐(0) 编辑
摘要: 递推公式:f[i]=f[i-1]+f[i-2]*2思路:1、对于i-1个来说剩两个直接补一个2*1的即可,有f[i-1]种2、对于i-2个来说,剩四个,有三种方法:a、一个2*2;b、两个横着的1*2;c、两个竖着的1*2,显然c中跟第一种冲突,所以有2*f[i-2]中 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 int k,i,n; 5 long f[33]={0,1,3}; 6 for(i=3;i<31;i++) 7 f[i]=f[i-1]+f[i-2]*2; 8 scanf("%d",&k);.. 阅读全文
posted @ 2013-05-10 14:53 飞向梦 阅读(137) 评论(0) 推荐(0) 编辑
摘要: 1 //高精度预处理 2 scanf("%s",s); 3 n=strlen(s); 4 for(i=1;i<=n;i++) //字符串处理 5 a[n-i+1]=s[i-1]-48; 6 a[0]=n; //a[0]存储第一个数的长度 7 scanf("%s",s); 8 n=strlen(s); 9 for(i=1;i<=n;i++)10 b[n-i+1]=s[i-1]-48;11 b[0]=n; //b[0]存储第二个数的长度 1 //高精度加法 2 void plus(int *a,int *b) 3 { 4 int i,l... 阅读全文
posted @ 2013-05-10 14:37 飞向梦 阅读(185) 评论(0) 推荐(0) 编辑
摘要: 这个题目也是递推,但是比较有意思的是要涉及到高精度递推式:f[i]=f[i-1]+f[i-2]+f[i-4]思路:1、i-1个排好了,只能再加一个F,共f[i-1]种2、i-2个排好了,a、可以加两个F;b、可以加两个M,但是两个F跟第一种冲突了,所以有f[i-2]种3、i-4个排好了,有FFFF, FFFM, MFFF, FFMM, MFFM, MMFF, MMMM这么多种,其中最后是M的跟第一种冲突,最后是FF的跟第二种冲突,只剩FFFF了,所以有f[i-4]种 至于高精度处理看高精度模板,至于数据存储需要灵活处理 题目传送门 1 #include<stdio.h> 2 #in 阅读全文
posted @ 2013-05-10 14:06 飞向梦 阅读(143) 评论(0) 推荐(0) 编辑
摘要: 递推式:f[i]=f[i-1]+2*f[i-2]分两种情况1、对于f[i-1],只剩下1米,只能铺三个1*1的了,共f[i-1]种2、对于f[i-2],有三种铺法,a、上边一个2*2,下边两个1*1;b、上边两个1*1,下边一个2*2;c、六个1*1;不过c情况跟第一种情况重复了,所以共2*f[i-2]种 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 long f[35]={0,1,3}; 5 long i,n,a; 6 scanf("%ld",&n); 7 for(i=3;i<35;i++) 8 f.. 阅读全文
posted @ 2013-05-10 11:02 飞向梦 阅读(275) 评论(0) 推荐(0) 编辑
摘要: 这个跟Fibonacci数列的来源——兔子的故事有一拼顺便贴上Fibonacci数列的通项公式,传说中的黄金分割数列递推式有两种:1、f[i] = f[i-1] + f[i-3];这种比较好理解,第i年的牛就等于去年的加上新生的牛2、f[i]=f[i-2]+f[i-3]+f[i-4] 这种不是很好理解,就看成f[i-1] = f[i-2]+f[i-4]吧。不过貌似第二种比第一种耗时间,第一种oj显示0ms,第二种显示15ms,有点不理解。。。 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 __int64 f[60]={1,1,2,3};. 阅读全文
posted @ 2013-05-10 10:54 飞向梦 阅读(143) 评论(0) 推荐(0) 编辑
摘要: 这个分割平面的问题挺有意思的,一不小心找到了个总结,也偷懒一下,详见:各种平面分割问题总结 题目传送门#include<stdio.h>int main(){ long n; __int64 a; scanf("%ld",&n); while(n--) { scanf("%I64d",&a); printf("%I64d\n",2*a*a-a+1); } return 0;} 阅读全文
posted @ 2013-05-10 10:40 飞向梦 阅读(108) 评论(0) 推荐(0) 编辑
摘要: (1)n条直线最多分平面问题题目大致如:n条直线,最多可以把平面分为多少个区域。 析:可能你以前就见过这题目,这充其量是一道初中的思考题。但一个类型的题目还是从简单的入手,才容易发现规律。当有n-1条直线时,平面最多被分成了f(n-1)个区域。则第n条直线要是切成的区域数最多,就必须与每条直线相交且不能有同一交点。 这样就会得到n-1个交点。这些交点将第n条直线分为2条射线和n-2条线断。而每条射线和线断将以有的区域一分为二。这样就多出了2+(n-2)个区域。故:f(n)=f(n-1)+n=f(n-2)+(n-1)+n……=f(1)+1+2+……+n=n(n+1)/2+1(2) 折线分平面 根 阅读全文
posted @ 2013-05-10 10:31 飞向梦 阅读(210) 评论(0) 推荐(0) 编辑
摘要: 递推式:f[i]=f[i-1]+f[i-2]说明:1、f[i-1]种情况剩两个小格,只能放一个(竖着放),就是f[i-1]种2、f[i-2]种情况剩四个小格,可以放两个,都横着放,算一种,都竖着放就跟第一种重复了,所以共f[i-2]种 题目传送门 1 #include<stdio.h> 2 __int64 f[51]={0,1,2,3}; 3 int main() 4 { 5 int n,i; 6 for(i=4;i<51;i++) 7 f[i]=f[i-1]+f[i-2]; 8 while(scanf("%d",&n)==1) 9 {10 ... 阅读全文
posted @ 2013-05-10 10:10 飞向梦 阅读(104) 评论(0) 推荐(0) 编辑
摘要: 这个题目至今还没想明白,想当初高考的时候都是(n-1)(n-1)(n-1)...(n-1)(n-1+n-2),好像是递推,不过好像不一样看解释:递推式f(n)=f(n-1)+2*f(n-2)思路:第n中情况由第n-1和n-2种情况决定1、n-2格颜色跟第一种一样,n-1格随便选,就有f(n-1)种2、n-2格颜色跟第一种不一样,这一格有2种情况,而n-1格只有一种情况,有2*f(n-2)种 题目传送门 1 #include<stdio.h> 2 __int64 f[51]={0,3,6,6}; 3 int main() 4 { 5 int n,i; 6 for(i=4;i<5 阅读全文
posted @ 2013-05-10 10:06 飞向梦 阅读(134) 评论(0) 推荐(0) 编辑
摘要: 递推:f[i]=f[i-2]+f[i-1];这个位置可以由左边位置过来也可以由左上位置过来需要注意:利用等效可以把首位置移到0,末位置移到b-a+1 题目传送门 1 #include<stdio.h> 2 __int64 f[50]; 3 int main() 4 { 5 int a,b,n,i; 6 f[0]=1; 7 f[1]=1; 8 f[2]=1; 9 for(i=3;i<50;i++)10 f[i]=f[i-2]+f[i-1];11 scanf("%d",&n);12 while(n--)13 {14... 阅读全文
posted @ 2013-05-10 09:53 飞向梦 阅读(142) 评论(0) 推荐(0) 编辑
摘要: 其实这个递推求解系列的题目挺有意思的,想明白了咋回事还是觉得有意思本层楼梯可以由下一层跳一次上来,也可以由下下层跳一次上来f[i]=f[i-2]+f[i-1];这种递推的问题尤其要注意初始化 题目传送门 1 #include<stdio.h> 2 int f[41]={0}; 3 int main() 4 { 5 int i,n,k; 6 f[1]=1;f[2]=1; 7 for(i=3;i<41;i++) 8 { 9 f[i]=f[i-2]+f[i-1];10 }11 scanf("%d",&n);12 while(n... 阅读全文
posted @ 2013-05-10 09:49 飞向梦 阅读(120) 评论(0) 推荐(0) 编辑
摘要: 看到这个题目号的时候激动了一下,呵呵,对一些数字比较敏感,就跟走到哪看到跟自己寝室号一样的号码……素数判定是数论里面基本的知识 题目传送门 1 #include<stdio.h> 2 #include<math.h> 3 4 int prime(int n) 5 { 6 int i; 7 if(n==2||n==3) return 1; 8 for(i=2;i<=sqrt(n);i++) 9 if(n%i == 0) return 0;10 return 1;11 }12 13 int main()14 {15 int x,y,i,f... 阅读全文
posted @ 2013-05-10 09:44 飞向梦 阅读(209) 评论(0) 推荐(0) 编辑
摘要: 这个题目记得高中的NOI里面就有,看来经典的终归是经典那如果对每个数对进行拆分可能会超时(尤其是比赛的时候),就想的竞赛中经典思想——以空间换时间,简单来说就是把三位数都给算一遍存储起来,是了就存1,不是存0,然后直接读入数据输出结果也可能是见过,也可能是多想了一下,发现水仙花数只有四个(这个。。。),进一步优化程序。 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 int a[] = {153,370,371,407}; 5 int m,n,i,flag; 6 while(scanf("%d%d",&m,&am 阅读全文
posted @ 2013-05-10 09:28 飞向梦 阅读(210) 评论(0) 推荐(0) 编辑
摘要: 这种可能就属于那种第一次见没有思路,但是知道答案后一想,奥,原来这样啊。。。 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 int n,max,t,a; 5 __int64 sum; //注意和的范围越界 6 scanf("%d",&t); 7 while(t--) 8 { 9 scanf("%d",&n);10 max = 0;11 sum = 0;12 while(n--)13 {14 ... 阅读全文
posted @ 2013-05-10 09:22 飞向梦 阅读(101) 评论(0) 推荐(0) 编辑
摘要: 题目比较简单,但是很有纪念意义,算是第一个遇到的积分题目,同时也发现原来计算机也不是万能的啊,需要预先准备一些工作才能交个计算机来完成。 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 double x1,y1,x2,y2,x3,y3; 5 double area,a; 6 int n; 7 scanf("%d",&n); 8 while(n--) 9 {10 scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3, 阅读全文
posted @ 2013-05-10 09:10 飞向梦 阅读(131) 评论(0) 推荐(0) 编辑