J - FatMouse's Speed dp

题目链接: https://vjudge.net/contest/68966#problem/J

找最长子串并且记录路径。

TLE代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<stdio.h>
using namespace std;
# define inf 0x3f3f3f3f
# define maxn 200000+10
int dp[maxn];
int road[maxn];
int a[maxn];
struct node
{
    int we;
    int sp;
    int num;
} q[maxn];
bool cmp(node t1,node t2)
{
    if(t1.sp!=t2.sp)return t1.sp>t2.sp;
    if(t1.sp==t2.sp&&t1.we!=t2.we)return t1.we>t2.we;
    return false;
}
int main()
{
    int t=1;
    while(~scanf("%d%d",&q[t].we,&q[t].sp))
    {
        q[t].num=t;
        t++;
    }
    t--;
    sort(q+1,q+t+1,cmp);
    memset(dp,0,sizeof(dp));
    memset(road,0,sizeof(road));
    dp[1]=1;
    road[1]=q[1].num;
    for(int i=2; i<=t; i++)
    {
        int maxx=0;
        int po=0;
        for(int j=i-1; j>=1; j--)
        {
            if(q[i].we>q[j].we&&q[i].sp<q[j].sp&&maxx<dp[j])
            {
                maxx=dp[j];
                po=q[j].num;
            }
        }
        road[i]=po;
        dp[i]=maxx+1;
    }
    int po=0;
    int maxx=0;
    for(int i=1; i<=t; i++)
    {
        if(dp[i]>maxx)
        {
            maxx=dp[i];
            po=i;
        }
    }
    int ans=0;
    printf("%d\n",maxx);
    int j=po;
    while(1)//在这个地方超时,其实可以通过递归来实现
    {
        for(int i=1; i<=t; i++)
        {
            if(q[i].num==j)
            {
                a[++ans]=j;
                j=road[i];
            }
        }
        if(ans==maxx)break;
    }
    for(int i=ans; i>=1; i--)
        printf("%d\n",a[i]);
    return 0;
}

AC代码;

#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
# define maxn 1000+10
struct node
{
    int num;
    int we;
    int sp;
} q[maxn];
int dp[maxn];
int road[maxn];
bool cmp(node t1,node t2)
{
    if(t1.sp!=t2.sp)return t1.sp>t2.sp;
    if(t1.sp==t2.sp&&t1.we!=t2.we)return t1.we<t2.we;
    return false;
}
void print(int k)
{
    if(k==0)return ;
    print(road[k]);
    printf("%d\n",q[k].num);
}
int main()
{
    int t=1;
    while(~scanf("%d%d",&q[t].we,&q[t].sp))
    {
        q[t].num=t;
        t++;
    }
    t--;
    sort(q+1,q+1+t,cmp);
    memset(dp,0,sizeof(dp));
    memset(road,0,sizeof(road));
    road[1]=0;
    dp[1]=1;
    for(int i=2; i<=t; i++)
    {
        int maxx=0;
        int po=0;
        for(int j=i-1; j>=1; j--)
        {
            if(q[i].we>q[j].we&&q[i].sp<q[j].sp&&maxx<dp[j])
            {
                maxx=dp[j];
                po=j;//与超时的代码相比,原来存储的是第j个的编号,而如果直接存储排完序后的编号的话,到时候倒着输出就可以了。
            }
        }
        dp[i]=maxx+1;
        road[i]=po;
    }
    int maxx=0;
    int po=0;
    for(int i=1; i<=t; i++)
    {
        if(dp[i]>maxx)
        {
            maxx=dp[i];
            po=i;
        }
    }
    printf("%d\n",maxx);
    print(po);
    return 0;
}

 

posted @ 2018-09-29 11:29  Let_Life_Stop  阅读(120)  评论(0编辑  收藏  举报