FatMouse's Speed【DP最长上升子序列】

  题目链接(无图)

  题目链接(有图)

FatMouse认为鼠标越胖,运行速度就越快。为了证明这一点,您希望将数据放在一组鼠标上,并将尽可能大的数据子集放入序列中,以便权重增加,但速度会降低。 

输入

输入包含一堆鼠标的数据,每行一个鼠标,由文件末尾终止。 

特定鼠标的数据将由一对整数组成:第一个以克为单位表示其大小,第二个以厘米每秒表示其速度。两个整数都在1到10000之间。每个测试用例中的数据将包含最多1000只小鼠的信息。 

两只小鼠可以具有相同的重量,相同的速度,或甚至相同的重量和速度。 

产量

你的程序应输出一系列数据; 第一行应包含数字n; 其余的n行应各包含一个正整数(每个整数代表一个鼠标)。如果这n个整数是m [1],m [2],...,m [n]则必须是 

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

和 

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

为了使答案正确,n应该与可能。 
所有不等式都是严格的:权重必须严格增加,速度必须严格降低。对于给定的输入,可能有许多正确的输出,您的程序只需要找到一个。 

样本输入

6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900

样本输出

4
4
5
9
7

 

这就是一道对其中一个元素排完顺序之后,对另一个元素求最长上升子序列的问题。

不过,其中有要注意的点就是memset()的函数不能给予数组赋值为1。

 

完整代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
using namespace std;
typedef long long ll;
int N;
struct node
{
    int w,s,id;
}a[3105];
int dp[3105], step[3105];     //dp记前面有几个,step记录前面那一步走的是
bool cmp(node e1, node e2)
{
    return e1.w==e2.w?(e1.s>e2.s):(e1.w<e2.w);
}
int main()
{
    int cnt=0;
    while(scanf("%d%d",&a[cnt].w,&a[cnt].s)!=EOF)
    {
        a[cnt].id=cnt+1;
        cnt++;
    }
    sort(a, a+cnt, cmp);
    for(int i=0; i<cnt; i++)
    {
        dp[i]=1;
        step[i]=0;
    }
    int last_blood=1, max_distance=1;
    for(int i=1; i<cnt; i++)
    {
        for(int j=0; j<i; j++)
        {
            if(a[j].s>a[i].s && a[j].w<a[i].w)
            {
                if(dp[i]<dp[j]+1)
                {
                    dp[i]=dp[j]+1;
                    step[i]=j;
                }
            }
        }
        if(dp[i]>max_distance)
        {
            max_distance=dp[i];
            last_blood=i;
        }
    }
    printf("%d\n",max_distance);
    int truely_truns[3105];
    for(int i=1; i<=max_distance; i++)
    {
        truely_truns[i]=last_blood;
        last_blood=step[last_blood];
    }
    for(int i=max_distance; i>=1; i--)
        printf("%d\n",a[truely_truns[i]].id);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值