对于二次函数:
,
- 判断两者“独立”,即有无交点:
如果
,那么如果
,那么
与
无交点(题目保证同一组测试数据中
)
如果
,那么就用
判断即可,其中
,
,
-
将
依次按照升序或降序排列后,那么满足传递性:
如果
与
独立,
与
独立,其中
,则
与
独立。具体证明过程略,分情况讨论
所以现在对于某一个函数
来说,求包含
的最大独立集合的大小,相当于求最长上升子序列,但是最长上升子序列里的
表示的是以
为结尾的最长子序列长度,所以求最大独立集合的大小,还得求
为开头的最长子序列长度,即用两个
数组
总代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
const int N = 3100;
int dp1[N], dp2[N];
struct Node{
int a, b, c, idx;
};
bool cmp(Node x, Node y){
if(x.a != y.a) return x.a < y.a;
else if(x.b != y.b) return x.b < y.b;
else return x.c < y.c;
}
bool check(Node x, Node y){
if(x.a == y.a) return (x.b == y.b);
else{
int sum1 = (x.b - y.b) * (x.b - y.b);
int sum2 = 4 * (x.a - y.a) * (x.c - y.c);
if(sum1 < sum2) return true;
else return false;
}
}
void solve(){
int n; cin >> n;
vector<Node> node(n + 10);
for(int i = 1; i <= n; i ++){
cin >> node[i].a >> node[i].b >> node[i].c;
node[i].idx = i;
dp1[i] = dp2[i] = 1;
}
sort(node.begin() + 1, node.begin() + 1 + n, cmp);
for(int i = 1; i <= n; i ++){
for(int j = 1; j < i; j ++){
if(check(node[i], node[j])) dp1[i] = max(dp1[i], dp1[j] + 1);
}
}
for(int i = n; i >= 1; i --){
for(int j = i + 1; j <= n; j ++){
if(check(node[i], node[j])) dp2[i] = max(dp2[i], dp2[j] + 1);
}
}
vector<int> ans(n + 10);
for(int i = 1; i <= n; i ++) ans[node[i].idx] = dp1[i] + dp2[i] - 1;
for(int i = 1; i <= n; i ++) cout << ans[i] << " ";
cout << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
cin >> tt;
while(tt --) solve();
return 0;
}



京公网安备 11010502036488号