Problem A:简单的图形覆盖
Time Limit:1000MS Memory Limit:65536K
Total Submit:201 Accepted:104
Description
有一个2*n的方格,要用若干个1*2的模块覆盖,模块可以横放,也可以竖放.问对于给定的n(n<=100),有多少种不同的覆盖方法.
Input
有多个测试用例,每个用例占一行,为一个正整数n
Output
对于每个测试用例,输出一行相应的结果
Sample Input
9
11
Sample Output
55
144
分析:
f(n)={ 1 n=1
2 n=2
f(n-1)+f(n-2) n>2
}
1 #include<stdio.h> 2 int A[101]; 3 int main() 4 { 5 int n,i; 6 while(scanf("%d",&n)!=EOF) 7 { 8 A[0]=1;A[1]=1; 9 if(n==1||n==0) printf("%d\n",A[0]); 10 else 11 { 12 for(i=2;i<n;i++) 13 A[i]=A[i-1]+A[i-2]; 14 printf("%d\n",A[i]); 15 } 16 } 17 return 0; 18 }
递归解决
1 #include <stdio.h> 2 #include <string.h> 3 int A[101]; 4 int f(int n) 5 { 6 memset(A,-1,sizeof(A)); 7 if (A[n]!=-1) return A[n]; 8 if(n==0||n==1) 9 { 10 A[n]=1; 11 } 12 else 13 { 14 A[n]=f(n-1)+f(n-2); 15 16 } 17 return A[n]; 18 } 19 int main() 20 { 21 int n; 22 while(scanf("%d",&n)!=EOF) 23 { 24 printf("%d\n",f(n)); 25 } 26 return 0; 27 }
Problem B:最大子段和
Time Limit:1000MS Memory Limit:65536K
Total Submit:574 Accepted:299
Description
有一组数,如-2 5 4 -3 7 的最大子段和是13, 是从5到7.
Input
第一行输入一个n(1〈 N〈=100 ) 表示这一组数有多长,第二行是N个数.
测试案例有多个,n=0时结束.
Output
输出这一组数的最大子段和.
Sample Input
5
-2 5 4 -3 7
10
9 -3 8 -28 98 -30 -20 50 -24 10
0
Sample Output
13
98
分析:
A
-2 |
5 |
4 |
-3 |
7 |
B 表示A0~Ai数段中包含第i个元素的最大子段和
-2 |
5 |
9 |
6 |
13 |
B[i]={
A[i] i=0;
max{ B[i-1]+A[i] , A[i] } i>0;
}
1 #include<stdio.h> 2 int A[101]; 3 int B[101]; 4 int main() 5 { 6 int n,i,max; 7 scanf("%d",&n); 8 while(n!=0) 9 { 10 for(i=0;i<n;i++) 11 scanf("%d",&A[i]); 12 B[0]=A[0]; 13 for(i=0;i<n;i++) 14 if(B[i-1]<0) B[i]=A[i]; 15 else 16 B[i]=B[i-1]+A[i]; 17 /* max=B[0]; 18 for(i=1;i<n;i++) if(max<B[i]) max=B[i]; 19 printf("%d\n",max); 20 scanf("%d",&n);*/ 21 printf("%d\n",B[n-1]); 22 23 } 24 return 0; 25 }
Problem C:最长公共子序列
Time Limit:1000MS Memory Limit:65536K
Total Submit:164 Accepted:99
Description
我们称序列Z=是序列X=的子序列当且仅当存在严格上升的序列,使得对j=1,2,...k,有Xij=Zj.比如Z=<a,b,f,c>是X=<a,b,c,f,b,c>的子序列.现在给出两个序列X和Y,任务是找到X和Y的最大公共子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列.
Input
输入包括多组测试数据.每组数据包括一行,给出两个长度不超过200的字符串,表示两个序列.两个字符串之间由若干个空格9开.
Output
对每组输入数据,输出一行,给出两个序列的最大公共子序列的长度.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
分析
Z[i][j]= {
0 i=0或j=0;
Z[i-1][j-1]+1 X[i]=Y[j];
max{ Z[i-1][j] , Z[i][j-1] } X[i]!=Y[j]
}
下标 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
|
Z[i][j] |
a |
b |
c |
f |
b |
c |
||
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
1 |
a |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
2 |
b |
0 |
1 |
2 |
2 |
2 |
2 |
2 |
3 |
f |
0 |
1 |
2 |
2 |
3 |
3 |
3 |
4 |
c |
0 |
1 |
2 |
3 |
3 |
3 |
4 |
5 |
a |
0 |
1 |
2 |
3 |
3 |
3 |
4 |
6 |
b |
0 |
1 |
2 |
3 |
3 |
4 |
4 |
X,Y下标从0开始,Z[i][j] 下标有效的从1开始
1 #include<stdio.h> 2 #include<string.h> 3 char x[201]; 4 char y[201]; 5 int z[200][200]; 6 int main() 7 { 8 int i,j,s,t,max; 9 while(scanf("%s%s",x,y)!=EOF) 10 { 11 s=strlen(x);t=strlen(y); 12 for(i=0;i<s;i++) 13 z[i][0]=0; 14 for(j=0;j<t;j++) 15 z[0][j]=0; 16 for(i=1;i<=s;i++) 17 for(j=1;j<=t;j++) 18 { 19 if(x[i-1]==y[j-1]) z[i][j]=z[i-1][j-1]+1; 20 else 21 { 22 if(z[i-1][j]>=z[i][j-1]) z[i][j]=z[i-1][j]; 23 else z[i][j]=z[i][j-1]; 24 } 25 } 26 /* max=z[0][0]; 27 for(i=0;i<=s;i++) 28 for(j=0;j<=t;j++) 29 if(z[i][j]>max) max=z[i][j];*/ 30 printf("%d\n",z[s][t]); 31 } 32 33 return 0; 34 }
Problem D:最长上升子序列
Time Limit:1000MS Memory Limit:65536K
Total Submit:456 Accepted:239
Description
一个数的序列bi,当b1<=b2<=b3..<=bn的时候,称这个序列是上升的。对于给定的一个序列(A1,A2,....,AN),可以得到一些上升的子序列(AI1,AI2,....AIK,这里1<=I1<=I2<=....<=IK<=N,比如,对于序列(1,7,3,5,9,4,8),有它的一些上升子序列,如(1,7),(3,4,8)等.这些子序列中最长的长度是4,比如子序列(1,3,5,8).
你的任务就是对于给定的序列,求出最长上升子序列的长度.
Input
输入有多个案例,每个案例占两行:
第一行是序列的长度N(1<=N<=1000).第二行给出序列中的N个整数,这些整数的取值范围都在0到10000.
Output
最长上升子序列的长度.
Sample Input
7
1 7 3 5 9 4 8
2
1036 3
Sample Output
4
1
分析
设置b[N],b[i]表示序列的第1个数到第i个数(保留第i个数)的最长上升子序列的长度。
b[i]=max(b[j])+1(a[j]<a[i],1<=j<=i<=n)
如果a[i]最小,则b[i]=1
A |
1 |
7 |
3 |
5 |
9 |
4 |
8 |
B |
1 |
2 |
2 |
3 |
4 |
3 |
4 |
1 #include<stdio.h> 2 int A[100],B[100]; 3 int main() 4 { 5 int n,i,j,max; 6 while(scanf("%d",&n)!=EOF) 7 { 8 for(i=0;i<n;i++) 9 scanf("%d",&A[i]); 10 B[0]=1; 11 for(i=1;i<n;i++) 12 { 13 max=0; 14 for(j=0;j<i;j++) 15 if(A[j]<A[i]&&B[j]>max) max=B[j]; 16 B[i]= max+1; 17 18 } 19 max=B[0]; 20 for(i=1;i<n;i++) 21 if(max<B[i]) max=B[i]; 22 printf("%d\n",max); 23 } 24 return 0; 25 }