这明明是一道很水很经典的入门DP。
然后我炸了。
题目就是在一条路两边有很多点 每个点都有在路的另一边与之对应的“朋友点”
然后连接所有点与“朋友点” 问最多有多少条不相交的线
第一下想到的是定义一个结构体 两两放一起然后排序 dp方程很好写
f[i]=max(f[i],f[j]+1)
在没有写dp方程之前我傻傻地根据样例想着排序, a.north<b.south 这样就可以很好地分成两个序列了。
4 5
2 4
5 2
1 3
3 1
4 5
2 4
5 2
1 3
3 1
这样排出来的话 就是
1 3
2 4
4 5
3 1
5 2 然后求一下south的最长上升子序列就好
2 4
4 5
3 1
5 2 然后求一下south的最长上升子序列就好
然而 这只是样例 因为我们写的mycmp没有规定a.north与b.north的关系,所以出排序得到的值不会像样例的这样听话
然后当时就试着改成pair (猛地拍脑袋 我怕不是傻了)
最后终于是弄出来了,。,,
#include<bits/stdc++.h>
using namespace std;
int x,y,n;
struct cities{
int north,south;
}city[6000]={};
int f[6000]={};
int maax=0;
inline int read()
{
int s=0;
char c=' ';
bool whs=1;
for(;c>'9'||c<'0';c=getchar()) if(c=='-') whs=false;
for(;c>='0'&&c<='9';s=s*10+c-48,c=getchar());
return whs?s:-s;
}
using namespace std;
int x,y,n;
struct cities{
int north,south;
}city[6000]={};
int f[6000]={};
int maax=0;
inline int read()
{
int s=0;
char c=' ';
bool whs=1;
for(;c>'9'||c<'0';c=getchar()) if(c=='-') whs=false;
for(;c>='0'&&c<='9';s=s*10+c-48,c=getchar());
return whs?s:-s;
}
void init()
{
x=read();
y=read();
if(y<x) swap(x,y);
n=read();
for(int i=1;i<=n;++i) city[i].north=read(),city[i].south=read();
}
{
x=read();
y=read();
if(y<x) swap(x,y);
n=read();
for(int i=1;i<=n;++i) city[i].north=read(),city[i].south=read();
}
bool mycmp(cities a,cities b)
{
return (a.north<b.north);//原来b写的south。。。
}
{
return (a.north<b.north);//原来b写的south。。。
}
void find()
{
sort(city+1,city+1+n,mycmp);
//最长上升子序列
{
sort(city+1,city+1+n,mycmp);
//最长上升子序列
for(int i=1;i<=n;++i)
{
f[i]=1;/*cout<<city[i].north<<' '<<city[i].south<<endl;*/
for(int j=1;j<=i;++j)
{
if(city[j].south<city[i].south&&f[j]+1>f[i]) f[i]=f[j]+1;
for(int i=1;i<=n;++i) maax=f[i]>maax?f[i]:maax;
}
}
}
{
f[i]=1;/*cout<<city[i].north<<' '<<city[i].south<<endl;*/
for(int j=1;j<=i;++j)
{
if(city[j].south<city[i].south&&f[j]+1>f[i]) f[i]=f[j]+1;
for(int i=1;i<=n;++i) maax=f[i]>maax?f[i]:maax;
}
}
}
int main()
{
init();
find();
{
init();
find();
cout<<maax;
return 0;
}
return 0;
}
emmmmmm dp学得实在太快了,,,再加上福建来的同学是如此的强大 下面教的dp啊图论啊还有别的算法emm我有点虚。。