您的位置:首页 > 其它

ACM 79. 渡轮问题(最长不下降子序列dp)

2014-08-17 10:46 211 查看


79. 渡轮问题

★☆ 输入文件:
maxxl.in
输出文件:
maxxl.out
简单对比

时间限制:1 s 内存限制:128 MB

Palmia 河在某国从东向西流过,并把该国分为南北两个部分。河的两岸各有 n 个城市,且北岸的每一个城市都与南岸的某个城市是友好城市,而且对应的关系是一一对应的。现在要求在两个友好城市之间建立一条航线,但由于天气的关系,所有航线都不能相交,因此,就不可能给所有的友好城市建立航线。
问题:当城市个数和友好关系建立之后,选择一种修建航线的方案,能建最多的航线而不相交。(若有多种方案,修建航线最多且城市数量相同,选择从前到后城市标号字典序小的那种方案.)
【输入格式】
输入由若干行组成,第一行有一个整数,n(1≤n≤10000);表示城市数。第2至n+1行依次是南岸城市的北岸友好城市编号。
【输出格式】
输出共两行,第一行是建立航线的数量。第二行是建立航线的北岸城市编号。
【输入样例】
输入文件名:maxxl.in
14

13

7

9

16

38

24

37

18

44

19

21

22

63

15
【输出样例】
输出文件名:maxxl.out
8

7 9 16 18 19 21 22 63

最长不下降子序列
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

#define MAX_N 100000

int n;
int city[MAX_N];
int cnt;

int dp[MAX_N];
int sel[MAX_N];

void PrintAns(int v)
{
if(sel[v]!=-1)
{
PrintAns(sel[v]);
printf(" %d",city[v]);
}
else
printf("%d",city[v]);
}

int main()
{
freopen("maxxl.in","r",stdin);
freopen("maxxl.out","w",stdout);

scanf("%d",&n);

for(int i=0;i<n;i++) scanf("%d",&city[i]);

memset(sel,-1,sizeof(sel));
for(int i=0;i<n;i++)
{
dp[i]=1;
for(int j=0;j<i;j++)
{
if(city[i]>=city[j])
{
if(dp[i]<dp[j]+1)
{
dp[i]=dp[j]+1;
sel[i]=j;
}
}
}
}
int k=0;
cnt=0;
for(int i=0;i<n;i++)
{
if(cnt<dp[i])
{
cnt=dp[i];
k=i;
}
}
printf("%d\n",cnt);
PrintAns(k);
printf("\n");

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: