线性DP简单题

Common Subsequence

Problem Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, …, xm> another sequence Z = <z1, z2, …, zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, …, ik> of indices of X such that for all j = 1,2,…,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.

Sample Input

abcfbc abfcab
programming contest
abcd mnp

Sample Output
4
2
0

这道题的大致意思就是给你两个字符串,要求你去求这两个字符串的最长公共子序列长度是多少。
这道题是最长公共子序列的模板题。
具体代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=1005;
char a[maxn];
char b[maxn];
int len1, len2;
int dp[maxn][maxn];
void LCS(int x,int y){
    for (int i = 1; i <= len1;i++){
        for (int j = 1; j <= len2;j++){
            if(a[i-1]==b[j-1])
                dp[i][j] = dp[i-1][j-1] + 1;
            else
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
        }
    }
} 
int main(){
    while(~scanf("%s",a)){
        scanf("%s", b);
        memset(dp, 0, sizeof dp);
        len1 = strlen(a);
        len2 = strlen(b);
        LCS(len1, len2);
        printf("%d\n", dp[len1][len2]);
    }
}

Super Jumping! Jumping! Jumping!
Problem Description
Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.

在这里插入图片描述

The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path.
Your task is to output the maximum value according to the given chessmen list.

Input
Input contains multiple test cases. Each test case is described in a line as follow:
N value_1 value_2 …value_N
It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int.
A test case starting with 0 terminates the input and this test case is not to be processed.

Output
For each case, print the maximum according to rules, and one line one case.

Sample Input
3 1 3 2
4 1 2 3 4
4 3 3 2 1
0

这道题的题意是:有一个游戏叫“超级跳跃”,它有一个棋盘和一些棋子,所有棋子上面标记一些正整数,或者start,或者end。玩家从起点开始,最后必须跳到终点。在跳跃的过程中,玩家会访问路径中的棋子,但是每个人都必须从一个棋子跳到另一个绝对大的棋子(可以假设起点是最小的,终点是最大的)。所有的玩家都不能倒退。一跳可以从一个棋子跳到下一个,也可以跨越多个棋子,甚至可以从起点直接到达终点。当然在这种情况下你得零分。一个球员只有当他能根据他的跳投方案得到更高的分数时,他才是赢家

这道题看题目,在看输入与输出,就是求最大上升子序列和,然后这道题可以作为最大上升子序列和的模板。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1005;
int ah[maxn];
int sum[maxn];
int main(){
    int n;
    while(~scanf("%d",&n)){  
        if(!n)break;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &ah[i]);
            sum[i]=ah[i]; 
            for (int j = i - 1; j > 0; j--)
            {
                if (ah[i] > ah[j])
                    sum[i] = max(sum[j] + ah[i], sum[i]);
            }
        }
        int maxx = *max_element(sum + 1, sum + 1 + n);
        printf("%d\n", maxx);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值