题目描述
BF的生日快到了,这一次,小东决定为BF送一份特别的生日礼物为其庆生。作为高智商中的佼佼者,BF在国外求学,因此小东无法与之一起庆生。小东计划送一个生日卡片,并通过特别的包装让BF永远难忘。
她决定把卡片套装在一系列的信封A = {a1, a2, …, an}中。小东已经从商店中购买了很多的信封,她希望能够用手头中尽可能多的信封包装卡片。为防止卡片或信封被损坏,只有长宽较小的信封能够装入大些的信封,同尺寸的信封不能套装,卡片和信封都不能折叠。
小东计算了邮寄的时间,发现她的时间已经不够了,为此找你帮忙包装,你能帮她吗?
输入
输入有若干组,每组的第一行包含三个整数n, w, h,1<=n<=5000, 1<=w, h<=10^6,分别表示小东手头的信封数量和卡片的大小。紧随其后的n行中,每行有两个整数wi和hi,为第i个信封的大小,1<=wi, hi<=10^6。
样例输入
2 1 1
2 2
2 2
3 3 3
5 4
12 11
9 8
输出
对每组测试数据,结果第一行中输出最多能够使用的信封数量,结果第二行中按使用顺序输出信封的编号。由于小东有洁癖,她对排在前面的信封比较有好感,若有多个信封可用,她喜欢用最先拿到的信封。另外别忘了,小东要求把卡片装入能够装的最小信封中。
如果卡片无法装入任何信封中,则在单独的行中输出0。
样例输出
1
1
3
1 3 2
解题思路:我们首先定义一个结构体,存放信封的长,宽,及其索引位置,然后把不能装卡片的信封去除掉(长宽较小的), 然后根据长或宽进行一个排序,这样就可以转化成一个最长递增子序列问题来求解了,2层循环动态规划就很容易求解了。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Node
{
int width;
int height;
int index; //节点的位置(索引)
Node(int w, int h, int idx) :width(w), height(h), index(idx) {}
};
bool cmp(Node node1, Node node2)
{
if (node1.width < node2.width)
return true;
if (node1.width == node2.width&&node1.height < node2.height)
return true;
if (node1.width == node2.width&&node1.height==node2.height&&node1.index<node2.index)
return true;
return false;
}
int main()
{
int i, j, k, n, temp1, temp2, w, h;
while (cin >> n >> w >> h)
{
vector<Node> vec;
for (i = 0; i < n; i++)
{
cin >> temp1 >> temp2;
if(temp1>w&&temp2>h) //只考虑比卡片大的信封
vec.push_back(Node(temp1, temp2, i + 1));
}
sort(vec.begin(), vec.end(), cmp);
n = vec.size();
if (n == 0)
cout << 0 << endl;
else
{
vector<int> a(n, 1), prev(n, -1), b; //最长递增子序列
for (i = 1; i < n; i++)
{
for (j = 0; j < i; j++)
{
if (vec[i].width > vec[j].width&&vec[i].height > vec[j].height)
{
if (a[i] < a[j] + 1)
{
a[i] = a[j] + 1;
prev[i] = j;
}
}
}
}
int res = 0, lastIndex = -1;
for (i = 0; i < n; i++)
{
if (a[i] > res)
{
res = a[i];
lastIndex = i;
}
}
cout << res << endl;
while (lastIndex != -1)
{
b.push_back(vec[lastIndex].index); //存放路径
lastIndex = prev[lastIndex];
}
reverse(b.begin(), b.end());
for (i = 0; i < b.size() - 1; i++)
cout << b[i] << " ";
cout << b[i] << endl;
}
}
return 0;
}