思路:
1)转化为有向无环图, 求已知终点的最长路径(dp的方法)
2)先按宽度排序, 然后求的按长度的最长递增子序列
代码1
/*DAG的方法 数据太大的时候内存超出*/
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 5005;
const int INF = 1 << 30;
struct Node
{
int w, h;
Node(){}
Node(int x, int y) : w(x), h(y){}
bool operator<(const Node &node)const
{
if(w < node.w && h < node.h)
return true;
return false;
}
};
vector<int> g[MAXN];
Node node[MAXN];
int dis[MAXN];
int father[MAXN];
void Init(int n)
{
for(int i = 0; i <= n; ++i)
dis[i] = -INF;
}
int DP(int s)
{
int &ans = dis[s];
if(ans >= 0) return ans;
ans = 0, father[s] = -1;
for(int i = 0; i < g[s].size(); ++i)
{
int v = g[s][i];
if(ans < DP(v) + 1)
{
ans = dis[v] + 1;
father[s] = v;
}
}
return ans;
}
void PrintPath(int s)
{
if(s == -1)
return;
printf("%d ", s);
PrintPath(father[s]);
}
int main()
{
#ifdef _LOCAL
freopen("F://input.txt", "r", stdin);
#endif
int n, w, h;
scanf("%d%d%d", &n, &w, &h);
node[0] = Node(w, h);
for(int i = 1; i <= n; ++i)
{
scanf("%d%d", &node[i].w, &node[i].h);
}
for(int i = 0; i < n; ++i)
{
for(int j = i + 1; j <= n; ++j)
{
if(node[i] < node[j] && node[0] < node[j])
g[i].push_back(j);
else if(node[j] < node[i] && node[0] < node[i])
g[j].push_back(i);
}
}
Init(n);
int result = DP(0);
printf("%d\n", result);
if(result)
PrintPath(father[0]);
}
代码2
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 5005;
struct Node
{
int id, w, h;
bool operator< (const Node &node) const
{
return w < node.w;
}
Node(){};
Node(int x, int y, int z) : id(x), w(y), h(z){}
};
vector<Node> seq;
int ans[MAXN];
int pre[MAXN];
int dp(int n)
{
int maxIndex = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = i - 1; j >= 1; --j)
{
if(seq[j].w < seq[i].w && seq[j].h < seq[i].h && ans[i] < ans[j] + 1)
{
ans[i] = ans[j] + 1;
pre[i] = j;
}
}
maxIndex = ans[i] > ans[maxIndex]? i : maxIndex;
}
return maxIndex;
}
void PrintSeq(int s)
{
if(s == 0) return;
PrintSeq(pre[s]);
printf("%d ", seq[s].id);
}
int main()
{
#ifdef _LOCAL
freopen("F://input.txt", "r", stdin);
#endif
int n, w, h;
scanf("%d%d%d", &n, &w, &h);
seq.push_back(Node(0, w, h));
int count = 0;
for(int i = 1; i <= n; ++i)
{
Node temp;
scanf("%d%d", &temp.w, &temp.h);
if(w < temp.w && h < temp.h)
{
++count;
temp.id = i;
seq.push_back(temp);
ans[count] = 1;
pre[count] = 0;
}
}
if(count == 0)
{
printf("0");
return 0;
}
sort(seq.begin(), seq.end());
int maxIndex = dp(count);
printf("%d\n", ans[maxIndex]);
PrintSeq(maxIndex);
return 0;
}