WA2次,然后改了一些似乎不重要的小地方,居然神奇的AC了。
让你从一个集合里找到一个最长的序列,其中W严格递增,S严格递减。最后输出该序列长度和此序列中每个元素的在原集合中的标号。
用结构体分别存下标,W,S。然后按W递增排序。
然后开始动规。
dp【i】表示以i为首元素的序列满足题目要求的最长长度。
dp【i】=max{dp【j】+1} (i.W>j.W且i.S<j.S)
另外开一个数组记录路径。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct Ele
{
int num,W,S;
};
Ele p[1005];
int dp[1005],path[1005];
bool cmp(Ele a,Ele b)
{
if(a.W==b.W) return a.S>b.S;
return a.W<b.W;
}
int main()
{
int n=1;
while(scanf("%d%d",&p[n].W,&p[n].S)!=EOF)
{
p[n].num=n;
n++;
}
memset(dp,0,sizeof(dp));
memset(path,-1,sizeof(path));
int mx;
sort(p+1,p+n,cmp);
for(int i=n-1; i>=1; --i)
{
bool ok=false;
mx=-1;
for(int j=i+1; j<n; ++j)
if(p[j].S<p[i].S&&p[j].W>p[i].W&&dp[j]>mx)
{
mx=dp[j];
path[i]=j;
ok=true;
}
if(ok) dp[i]=1+mx;
else
{
dp[i]=1;
path[i]=0;
}
}
mx=-1;
int key;
for(int i=1; i<n; ++i)
if(dp[i]>mx)
{
mx=dp[i];
key=i;
}
printf("%d\n",mx);
while(key)
{
printf("%d\n",p[key].num);
key=path[key];
}
return 0;
}