给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。现在增加一个要求,即还需要输出该子序列的第一个和最后一个元素。
Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.
Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.
Input Specification:
Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (<= 10000). The second line contains K numbers, separated by a space.
Output Specification:
For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.
Sample Input:10 -10 1 2 3 4 -5 -23 3 7 -21Sample Output:
10 1 4
#include
#include
using namespace std;
const int maxn=10010;
struct DP{
int start,end;
int data;
};
int main(){
int n,i;
cin>>n;
int num=0;
//while(n!=0){
DP dp[maxn];
int a[maxn];
for(i=0;i>a[i];
if(a[i]<0) num++;
}
if(num==n){
cout<<"0 "<a[i]){
dp[i].data=dp[i-1].data+a[i];
dp[i].start=dp[i-1].start;
dp[i].end=i;
}
else if(dp[i-1].data+a[i]maxx){
j=i;
maxx=dp[i].data;
}
}
printf("%d %d %d\n",maxx,a[dp[j].start],a[dp[j].end]);
//cin>>n;
//}
return 0;
}
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。现在增加一个要求,即还需要输出该子序列的第一个和最后一个元素。
测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( K<= 10000 ),第2行给出K个整数,中间用空格分隔,每个数的绝对值不超过100。当K为0时,输入结束,该用例不被处理。
对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
5
-3 9 -2 5 -4
3
-2 -3 -1
0
12 9 5
0 -2 -1
这是一道稍微有点难度的动态规划题。
首先可以想到的做法是枚举每个区间的和,预处理sum[i]来表示区间[1, i]的和之后通过减法我们可以O(1)时间获得区间[i, j]的和,因此这个做法的时间复杂度为O(n^2)。
然后这题的数据范围较大,因此还需作进一步优化才可以AC。记第i个元素为a[i],定义dp[i]表示以下标i结尾的区间的最大和,那么dp[i]的计算有2种选择,一种是含有a[i-1],一种是不含有a[i-1],前者的最大值为dp[i-1]+a[i],后者的最大值为a[i]。而两者取舍的区别在于dp[i-1]是否大于0。
//问题A: 最大和连续子序列
#include
#include
using namespace std;
struct SUM{
int start,end;
int data;
};
int main(){
int n,i;
cin>>n;
while(n!=0){
int num=0;
int a[10010];
SUM dp[10010];
for(i=0;i>a[i];
if(a[i]<0) num++;
}
if(num==n){
cout<<"0 "<=a[i]){
dp[i].data=a[i]+dp[i-1].data;
dp[i].start=dp[i-1].start;
dp[i].end=i;
}
else{
dp[i].data=a[i];
dp[i].start=dp[i].end=i;
}
}
int maxx=dp[0].data;
int j=0;
for(i=1;imaxx){
maxx=dp[i].data;
j=i;
}
}
printf("%d %d %d\n",dp[j].data,a[dp[j].start],a[dp[j].end]);
}
cin>>n;
}
return 0;
}
一个数列ai如果满足条件a1 < a2 < ... < aN,那么它是一个有序的上升数列。我们取数列(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)。
现在你要写一个程序,从给出的数列中找到它的最长上升子序列。输入包含两行,第一行只有一个整数N(1 <= N <= 1000),表示数列的长度。
第二行有N个自然数ai,0 <= ai <= 10000,两个数之间用空格隔开。
输出只有一行,包含一个整数,表示最长上升子序列的长度。
71 7 3 5 9 4 8
4
//问题A: 最长上升子序列
#include
#include
using namespace std;
int main(){
int n;
int buf[1010];
int dp[1010]={0};
cin>>n;
int i,j;
for(i=0;i>buf[i];
}
int ans=-1;
for(i=0;idp[i]){
dp[i]=dp[j]+1;
}
}
ans=ans>dp[i]?ans:dp[i];
}
printf("%d",ans);
return 0;
}
abcfbc abfcab
programming contest
abcd mnp
4
2
0
//问题A: 最长公共子序列
#include
#include
#include
using namespace std;
int max(int a,int b){
return a>b?a:b;
}
int main(){
char a[110],b[110];
while(scanf("%s %s",a,b)!=EOF){
int i,j;
int dp[110][110];
int len1=strlen(a);
int len2=strlen(b);
char aa[110],bb[110];
for(i=0;i
输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看相同。如abba和yyxyy。在判断回文时,应该忽略所有标点符号和空格,且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符串长度不超过5000,且占据单独的一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的。
一行字符串,字符串长度不超过5000。
字符串中的最长回文子串。
Confuciuss say:Madam,I'm Adam.
Madam,I'm Adam
//问题A: 【字符串】最长回文子串
//去掉空格、标点、大小写,判断回文
//输出原文
#include
#include
struct STR{
char a;
int no;
}str[5010];
int dp[5010][5010];
int deal(char &a){
if(a>='0'&&a<='9') return 1;
if(a>='a'&&a<='z'){
a=a-'a'+'A';
return 1;
}
if(a>='A'&&a<='Z') return 1;
return 0;
}
int main(){
memset(dp,0,sizeof(dp));
char buf[5010];
gets(buf);
int len=strlen(buf);
int i,j=0,k;
for(i=0;i
Given a string, you are supposed to output the length of the longest symmetric sub-string. For example, given "Is PAT&TAP symmetric?", the longest symmetric sub-string is "s PAT&TAP s", hence you must output 11.
Input Specification:
Each input file contains one test case which gives a non-empty string of length no more than 1000.
Output Specification:
For each test case, simply print the maximum length in a line.
Sample Input:Is PAT&TAP symmetric?Sample Output:
11
#include
#include
#include
#include
#include
using namespace std;
int dp[1001][1001];
int main(){
string str;
getline(cin,str);
memset(dp,0,sizeof(dp));
int i;
int ans=1;
for(i=0;i
Eva is trying to make her own color stripe out of a given one. She would like to keep only her favorite colors in her favorite order by cutting off those unwanted pieces and sewing the remaining parts together to form her favorite color stripe.
It is said that a normal human eye can distinguish about less than 200 different colors, so Eva's favorite colors are limited. However the original stripe could be very long, and Eva would like to have the remaining favorite stripe with the maximum length. So she needs your help to find her the best result.
Note that the solution might not be unique, but you only have to tell her the maximum length. For example, given a stripe of colors {2 2 4 1 5 5 6 3 1 1 5 6}. If Eva's favorite colors are given in her favorite order as {2 3 1 5 6}, then she has 4 possible best solutions {2 2 1 1 1 5 6}, {2 2 1 5 5 5 6}, {2 2 1 5 5 6 6}, and {2 2 3 1 1 5 6}.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=200) which is the total number of colors involved (and hence the colors are numbered from 1 to N). Then the next line starts with a positive integer M (<=200) followed by M Eva's favorite color numbers given in her favorite order. Finally the third line starts with a positive integer L (<=10000) which is the length of the given stripe, followed by L colors on the stripe. All the numbers in a line are separated by a space.
Output Specification:
For each test case, simply print in a line the maximum length of Eva's favorite stripe.
Sample Input:6 5 2 3 1 5 6 12 2 2 4 1 5 5 6 3 1 1 5 6Sample Output:
7
//最长不下降子序列解法
#include
#include
using namespace std;
const int maxn=100010;
int hhash[201];//为个可能喜欢的颜色建hash
int buf[maxn];
int dp[maxn];
int main(){
int n,m,i;
cin>>n;//color编号-n
for(i=0;i<201;i++) hhash[i]=-1;
cin>>m;
for(i=0;i>a;
hhash[a]=i;
}
cin>>m;
int j=0,k;
for(i=0;i>a;
if(hhash[a]!=-1) buf[j++]=hhash[a];//只筛选出喜欢的,并且转化为hash值
}
int ans=-1;
for(i=0;idp[i]){
dp[i]=dp[k]+1;
}
}
ans=ans>dp[i]?ans:dp[i];
}
printf("%d",ans);
return 0;
}
//最长不下降子序列解法
#include
#include
using namespace std;
const int maxn=100010;
int buf[maxn];
int dp[201][maxn];
int a[201]={0};
int b[maxn];
int main(){
int n,m1,m2,j,i;
cin>>n;//color编号-n
cin>>m1;
for(i=1;i<=m1;i++){
cin>>a[i];
}
cin>>m2;
for(i=1;i<=m2;i++){
cin>>b[i];
}
for(i=0;i<=m1;i++) dp[i][0]=0;
for(i=0;i<=m2;i++) dp[0][i]=0;
for(i=1;i<=m1;i++){
for(j=1;j<=m2;j++){
if(a[i]==b[j]){
dp[i][j]=max(dp[i-1][j],dp[i][j-1])+1;
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
printf("%d",dp[m1][m2]);
return 0;
}