LIS application
http://codeforces.com/contest/4/problem/D
这道题目是一道LIS,后来也想到了,但是想dp[i]是以为尾元素为序列的最大值,从输入数据开始dp即使找到了最大值他的起点也未必是>w >h的,
然后觉得有点麻烦了,后来发现可以先把<=的都删掉,过滤一遍,这样剩下的任意一个值都是符合头的性质的,也就是严格的从头开始的递增序列。
但是WA了一次,发现dp之后构造解,忘记加递增的条件了(!j || (data[j-1].w<data[i-1].w && data[j-1].h<data[i-1].h)), 还漏了一次!j的判断,
这里其实因为只要返回任意解,直接for就可以解决了,如果是返回所有解,由于有多个分支,因此需要dfs每个分支了。
struct Node
{
int w, h;
int in;
bool operator<(Node n) const
{
if(w!=n.w) return w<n.w;
else return h<n.h;
}
};
int main()
{
/*
#ifndef ONLINE_JUDGE
freopen ("in.txt" , "r" , stdin);
freopen ("out.txt" , "w" , stdout);
#endif
*/
int n, w, h, w1, h1;
cin>>n>>w>>h;
int dp[n+1];
vector<Node> data;
for(int i=0;i<n;i++)
{
cin>>w1>>h1;
if(w1>w && h1>h)
data.push_back({w1,h1,i+1});
}
sort(data.begin(), data.end());
n=data.size();
dp[0]=0;
int maxi=0, maxdp=dp[0];
for(int i=1;i<=n;i++)
{
dp[i]=0;
for(int j=0;j<i;j++)
{
if(!j || (data[j-1].w<data[i-1].w && data[j-1].h<data[i-1].h))
dp[i]=max(dp[i], dp[j]+1);
}
if(dp[i]>maxdp) maxdp=dp[i], maxi=i;
}
vector<int> ans;
for(int i=maxi;i>0;)
{
ans.push_back(data[i-1].in);
int j;
for(j=0;j<i;j++)
{
if(dp[i]==dp[j]+1 && (!j || (data[j-1].w<data[i-1].w && data[j-1].h<data[i-1].h)))
break;
}
i=j;
}
reverse(ans.begin(), ans.end());
cout<<ans.size()<<endl;
for(auto e: ans) cout<<e<<" ";
cout<<endl;
return 0;
}