【发布时间】:2014-05-23 08:43:07
【问题描述】:
我正在尝试在http://acm.sgu.ru/problem.php?contest=0&problem=199 解决美丽的人问题,但在某些测试用例中我得到了错误的答案。
一个城市最负盛名的体育俱乐部正好有 N 个成员。 它的每个成员都强壮而美丽。更准确地说,第 i 个 该俱乐部的成员(成员按他们进入的时间编号 俱乐部)有实力斯和美人碧。由于这是一个非常 有声望的俱乐部,其成员非常富有,因此 非凡的人,所以他们常常极度憎恨对方。 严格来说,俱乐部的第 i 个成员 X 先生讨厌俱乐部的第 j 个成员 如果 Si ≤ Sj 且 Bi ≥ Bj 或如果 Si ≥ Sj 且 Bi ≤ Bj(如果 X先生的两个属性都大于相应的属性 Y 先生,另一方面,如果他的两个 属性少,他很尊重Y先生)。
为了庆祝新的 2003 年,俱乐部的管理部门是 计划组织一个聚会。但是他们害怕如果两个 互相憎恨的人会同时参加聚会,之后 一两杯他们就会开始打架。所以没有两个讨厌的人 应该互相邀请。另一方面,为了保住俱乐部 presti≥在适当的级别,行政部门希望邀请作为 尽可能多的人。
做行政中唯一不怕碰的人 一台计算机,你要编写一个程序来找出谁 邀请参加聚会。
输入
输入文件的第一行包含整数 N — 的数量 俱乐部成员。 (2 ≤ N ≤ 100,000)。接下来的 N 行包含两个 每个数字 - 分别为 Si 和 Bi ( 1 ≤ Si, Bi ≤ 10^9 )。
输出
在输出文件的第一行打印最大数量 可以被邀请参加聚会的人。在第二行输出 N integers — 以任意顺序邀请的成员数量。如果 存在多种解决方案,输出任何一种。
Sample test(s)
Input
4
1 1
1 2
2 1
2 2
Output
2
1 4
基本上我的做法是:
- 首先根据 Beauty[] 对数组 Strength[] 进行排序
- 采用一个数组 D[i] 存储最大 lis 直到 i
- 最佳解决方案 =
D(i) = { 1 + Max ( D(j) ) }其中j < i和D[i] = max{ D[j] +1 }forj < i和Strength[j] < Strength[i]和Beauty[j] < Beauty[i],如果没有这样的 j 则D(i) = 1
我的方法有什么遗漏吗?
我的解决方案:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct {
long int s;
long int b;
} c_type;
int compare(const c_type &a,
const c_type &b) {
return a.s < b.s;
}
int main( )
{
int n = 0;
cin>>n;
vector<c_type> ct;
ct.resize(n);
//vector<long int> b(n,-1);
//s[0] = 1;
//s[1] = 1;
//s[2] = 2;
//s[3] = 2;
//b[0] = 1;
//b[1] = 2;
//b[2] = 1;
//b[3] = 2;
vector<long int> d(n,1);
vector<long int> p(n,-1);
long int max = -1;
long int bestEnd = -1;
for(int i = 0 ;i<n;i++)
{
cin>>ct[i].s>>ct[i].b;
}
sort (ct.begin(), ct.end(), compare);
for(int i = 1 ; i < n ;i++)
{
for(int j = i-1 ; j>=0 ; j--)
{
if(((d[j] + 1) > d[i]) and (ct[j].b < ct[i].b) and (ct[j].s < ct[i].s))
{
d[i] = d[j]+1;
p[i] = j;
}
}
if(max < d[i])
{
max = d[i];
bestEnd = i;
}
}
cout<<max<<endl;
if(bestEnd != -1)
while(bestEnd not_eq -1)
{
cout<<bestEnd+1<<" ";
bestEnd = p[bestEnd];
}
return 0;
}
【问题讨论】:
-
这是LIS(最长递增子序列),您的解决方案似乎还可以。假设您有实施错误? (您可以在此处发布您的解决方案)。
-
@juver 我已经更新了我的解决方案。
-
您的解决方案输出的人员索引不正确。对输入进行排序后,它们的顺序发生了变化。只需将附加索引存储到您的结构中并使用它。但是,您的代码将 TLE,因为 O(N^2)。您需要 O(NlogN) 解决方案,这是 LIS 的经典解决方案。
-
@juver 您应该将此作为答案发布。对于 OP,除了 juver 所说的,如果可以邀请的最大可能成员数量为 1,您也不会正确输出。
-
这个俱乐部的每个人都讨厌自己 ;-) (因此,可以在不爆发战斗的情况下被邀请参加派对的最大人数是 0。Rockin'。 )
标签: c++ algorithm dynamic-programming