dp(最长上升,最长公共子序列,最大子序列和,最大下降)

鹏神意外得到了神灯。

  神灯中冒出了灯神,灯神说道:“我将给你一个有序的数列,你可以在保证原有顺序不变的前提下,挑出任意多的数。如果你挑出的数字是严格升序的,那么这段数字的个数就是你女朋友的个数。”

  “妈的智障。”鹏神骂道。

  但是鹏神还是希望自己能有尽可能多的女朋友。所以他求救于你,希望你能帮他算出他最多能有多少女朋友。

Input

  输入包含多组数据。

  第一行是以为整数N,表示灯神给出的数列的长度。(1≤N≤1000)

  第二行包含N个整数,即是灯神给出的序列。

Output

  对于每组输入数据,请输出最终答案,即鹏神最多可以得到的女朋友个数。

Sample Input

7
1 7 3 5 9 4 8

Sample Output

4

Hint

在样例中,鹏神可以挑出1、3、5、9 或者1、3、5、8,都是4个数字。

#include<iostream>
#include<stdio.h> 
using namespace std;
int main(void)
{
    int i,j,n;
    int a[1001];
    int b[1001];
    int max;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=1;
    }
    for(i=0;i<n;i++)
    {
        max=0;
        for(j=0;j<i;j++)
        {
            if(a[i]>a[j]&&b[j]>max)
            {
                max=b[j];
            }
        }
        b[i]=max+1;
    }
    max=0;
    for(i=0;i<n;i++)
    {
        if(max<b[i])
            max=b[i];
    }
    printf("%d\n",max);
    return 0;
}

 

Cry对于泡妹子十分不熟练,在见到小姐姐后十分紧张,这时,他想起了ACJ对他的教诲,于是他决定尽可能找到自己与小姐姐的共同点。Cry靠他强大的人格魅力获取了小姐姐的基因片段,同时他也提供了自己的基因片段。

题目描述

现在我们假定,他们的共同点个数为两个片段的最长公共子序列中元素个数,Cry嘤嘤地cry了,因为他完全不会做。他的幸福生活只能靠在座的各位了!

输入格式

多组输入,每行有两个字符串,根据ACJ的经验,对小姐姐问来问去是很失礼的一件事,因此每个基因片段长度不超过1000

输出格式

每行一个答案,表示每组数据中他们的公共点个数

输入样例

abcfbc abfcab
programming contest 
abcd mnp

输出样例

4
2
0

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1000+5;
 
int n,m;
int dp[maxn][maxn];
char s1[maxn],s2[maxn];
 
int main()
{
    while(scanf("%s%s",s1,s2)==2)
    {
        n=strlen(s1);//s1串长度
        m=strlen(s2);//s2串长度
        memset(dp,0,sizeof(dp));
 
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(s1[i-1]==s2[j-1])
                dp[i][j]=dp[i-1][j-1]+1;
            else
                dp[i][j]=max( dp[i-1][j] , dp[i][j-1] );
        }
        printf("%d\n",dp[n][m]);
    }
    return 0;
}

众所周知,cth很喜欢吃糖,有天他碰到了N个人 ,每个人会给他Ai块糖 ;但有的人非常凶 ,他会从cth那里把糖抢走 ,如果Ai是负的 ,则表示那个人会从cth那里抢走Ai块糖 .cth只能与连续的几个人接触 ,由于他比较蠢 ,所以他会告诉你对于每个人它的A值 ,然后求你帮他算出他能拿到最多糖的区间的起点 ,终点 ,以及糖的数目. 对于样例一: cth从第一到第四个人都接触 ,然后得到14块糖 ,这是坠吼的方案. 

Input

输入数据的第一行是一个整数T(1<=T<=20)表示测试实例的个数,然后是T行数据,每一行的开始是一个整数N(1<=N<=100000),然后是N个整数(-1000<=0<=1000). 

Output

对于每个测试实例,你要输出两行,第一行是"Case #:",#是第#组数据的意思,第二行包含三个整数,糖的数目最大值,子区间的起始位置,子区间的结束位置。
注意每两组测试样例之间有一个空行。 

Sample Input

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

Sample Output

Case 1:
14 1 4

Case 2:
7 1 6

 

#include<iostream>
#define N 100010
using namespace std;
int a[N],d[N];
int main()
{
    int T,n,i,max,k,f,e;
    cin>>T;
    k=1;
    while(T--)
    {
        cin>>n;
        for(i=1;i<=n;i++)
            cin>>a[i];
        d[1]=a[1];
        for(i=2;i<=n;i++)
        {
            if(d[i-1]<0) d[i]=a[i];
            else d[i]=d[i-1]+a[i];
        }
        max=d[1];e=1;
        for(i=2;i<=n;i++)
        {
            if(max<d[i])
            {
                max=d[i];e=i;
            }
        }
        int t=0;
        f=e;
        for(i=e;i>0;i--)
        {
            t=t+a[i];
            if(t==max)    f=i;
        }
        cout<<"Case "<<k++<<":"<<endl<<max<<" "<<f<<" "<<e<<endl;
        if(T) cout<<endl;
    }
    return 0;
}

 

 

某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。

Input

输入有两行, 
第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25), 
第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。

Output

输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。 

Sample Input

8
300 207 155 300 299 170 158 65

Sample Output

6

#include<stdio.h>
#include<string.h>
 
int Height[26];
int MaxLen[26];
 
void LIS(int k){
    memset(MaxLen,0,sizeof(MaxLen));
    for(int i = 1;i <= k; i++){
        MaxLen[i] = 1;
        //遍历其前所有导弹高度
        for(int j = 1;j < i;j++){
            //如果当前导弹高度小于等于j号导弹
            if(Height[i] <= Height[j]){
                //把当前导弹放在j号导弹后,其最长不增子序列长度为j号导弹结尾的最长不增子序列长度 + 1
                int preMax = MaxLen[j] + 1;
                if(preMax > MaxLen[i]){
                    MaxLen[i] = preMax;
                }
            }
        }
    }
}
 
int main()
{
    int N,i;
    while(scanf("%d",&N)!=EOF)
    {
        for(i = 1;i <= N;i++)
        {
            scanf("%d",&Height[i]);
        }
        LIS(N);
        int Max = -1;
        //输出最长不增子序列的长度即能拦截的导弹数
        for(i = 1;i <= N;i++){
            if(Max < MaxLen[i]){
                Max = MaxLen[i];
            }
        }
        if(N != 0){
            printf("%d\n",Max);
        }
    }
    return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值