(最长上升子序列 并记录过程)FatMouse's Speed -- hdu -- 1160

http://acm.hdu.edu.cn/showproblem.php?pid=1160

FatMouse‘s Speed

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12338    Accepted Submission(s): 5405
Special Judge

Problem Description

FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing.

Input

Input contains data for a bunch of mice, one mouse per line, terminated by end of file.

The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice.

Two mice may have the same weight, the same speed, or even the same weight and speed.

Output

Your program should output a sequence of lines of data; the first line should contain a number n; the remaining n lines should each contain a single positive integer (each one representing a mouse). If these n integers are m[1], m[2],..., m[n] then it must be the case that

W[m[1]] < W[m[2]] < ... < W[m[n]]

and

S[m[1]] > S[m[2]] > ... > S[m[n]]

In order for the answer to be correct, n should be as large as possible.
All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one.

Sample Input

6008 1300

6000 2100

500 2000

1000 4000

1100 3000

6000 2000

8000 1400

6000 1200

2000 1900

Sample Output

4

4

5

9

7

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>

using namespace std;
#define N 10005
#define oo 0x3f3f3f3f

/**

感觉有点用导弹防御的思想
每次记录从 0 到 i 的最长个数
并用 pre[i] 记录 i 点是从哪个点过来的

**/

/// number 是记录它原来的位置

struct node
{
    int w, s, number;
}a[N];

/// pre[] 是个很好的记录方式,可以记录它的是从哪个过来的(它的上一步)

int dp[N], pre[N];

/// 先按 w 从小到大排, 再按 s 从大到小排
int cmp(node n1, node n2)
{
    if(n1.w!=n2.w)
       return n1.w < n2.w;
    return n1.s > n2.s;
}

int main()
{
    int i=1, j, n;

    memset(a, 0, sizeof(a));
    memset(dp, 0, sizeof(dp));

    while(scanf("%d%d", &a[i].w, &a[i].s)!=EOF)
    {
        a[i].number = i;
        i++;
    }

    n=i;
    sort(a+1, a+i+1, cmp);

/**
    for(i=1; i<n; i++)
        printf("%d %d %d\n", a[i].number, a[i].w, a[i].s);
**/

    for(i=1; i<n; i++)
    {
        pre[i] = i;
        dp[i] = 1;
        for(j=1; j<i; j++)
        {
            if(a[i].w!=a[j].w && a[i].s<a[j].s)
            {
                if(dp[i]<dp[j]+1)
                {
                     pre[i] = j;
                     dp[i] = dp[j] + 1;
                }
            }
        }
    }

    int Max=-oo, index=0;

    for(i=1; i<n; i++)
    {
        if(dp[i]>Max)
        {
            Max = dp[i];
            index = i;
        }
    }

    printf("%d\n", Max);
    i=0;
    int b[N]={0};
    while(pre[index]!=index)
    {
        b[i++] = a[index].number;
        index = pre[index];
    }

    printf("%d\n", a[index].number);
    for(j=i-1; j>=0; j--)
        printf("%d\n", b[j]);

    return 0;
}

(最长上升子序列 并记录过程)FatMouse's Speed -- hdu -- 1160

时间: 2024-10-13 14:44:51

(最长上升子序列 并记录过程)FatMouse's Speed -- hdu -- 1160的相关文章

FatMouse&#39;s Speed hdu 1160(动态规划,最长上升子序列+记录路径)

http://acm.hdu.edu.cn/showproblem.php?pid=1160 题意:现给出老鼠的体重与速度,要求你找出符合要求的最长子序列.       要求是 W[m[1]] < W[m[2]] < ... < W[m[n]](体重) && S[m[1]] > S[m[2]] > ... > S[m[n]] (速度) 分析:有两个变量的话比较不好控制,自然需要先排序.再仔细思考的话,觉得和之前做的防御导弹有点类似,都是求最多能有几个符合

FatMouse&#39;s Speed HDU - 1160 最长上升序列,

#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; struct node { int w, s; int index; //储存标号 } mouse[1005]; //小鼠的信息 //先体重,后速度 bool cmp(node a,node b) { if(a.w==b.w) return a.s<b.s; retu

CSU 1225 最长上升子序列并记录其个数

1 for(int j=0;j<i;j++){ 2 if(h[i] > h[j]){ 3 if(len[i] == len[j] + 1) cnt[i]+=cnt[j]; 4 if(len[i] < len[j] + 1) len[i] = len[j] + 1 , cnt[i] = cnt[j]; 5 } 6 //身高相同的情况统计 7 /*else if(h[i] == h[j]){ 8 if(len[i] == len[j]) cnt[i] += cnt[j]; 9 if(len[

O(nlogn)的最长上升子序列并且记录所选择的数 模板

#include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 10000 + 10; int A[MAXN]; int lis[MAXN]; int f[MAXN]; int stack[MAXN

hdu-1160 FatMouse&#39;s Speed 【最长上升子序列】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1160 FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9965    Accepted Submission(s): 4427 Special Judge Problem Description FatMo

动规讲解基础讲解七——最长单增子序列

(LIS Longest Increasing Subsequence)给定一个数列,从中删掉任意若干项剩余的序列叫做它的一个子序列,求它的最长的子序列,满足子序列中的元素是单调递增的. 例如给定序列{1,6,3,5,4},答案是3,因为{1,3,4}和{1,3,5}就是长度最长的两个单增子序列. 处看此题,怎么做? 万能的枚举?枚举全部2^n个子序列,找出最长的,固然可以,就是复杂度太高.我们为什么要枚举呢?因为要知道取了哪些数,其实我们只需要考虑上一个数和取了几个数就可以了吧?因为单增的意思

动态规划5-最长单增子序列

(LIS Longest Increasing Subsequence)给定一个数列,从中删掉任意若干项剩余的序列叫做它的一个子序列,求它的最长的子序列,满足子序列中的元素是单调递增的. 例如给定序列{1,6,3,5,4},答案是3,因为{1,3,4}和{1,5,4}就是长度最长的两个单增子序列. 处看此题,怎么做? 万能的枚举?枚举全部2^n个子序列,找出最长的,固然可以,就是复杂度太高.我们为什么要枚举呢?因为要知道取了哪些数,其实我们只需要考虑上一个数和取了几个数就可以了吧?因为单增的意思

[FatMouse&#39;s Speed] LIS

Description HDU-1160 FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are incr

HDU 1160 FatMouse&#39;s Speed 动态规划 记录路径的最长上升子序列变形

题目大意:输入数据直到文件结束,每行两个数据 体重M 和 速度V,将其排列得到一个序列,要求为:体重越大 速度越低(相等则不符合条件).求这种序列最长的长度,并输出路径.答案不唯一,输出任意一种就好了. 题目思路:这是个最长上升子序列的问题,我们按W的升序进行排序,若W相等则按V的降序排序.用Pre[]记录当前点的前驱节点,Last记录序列最后一个点,maxn记录最长长度,完成动规后可根据Last和Pre[]输出路径. #include<cstdio> #include<stdio.h&