HDU1025贫富平衡

时间:2023-03-09 19:08:09
HDU1025贫富平衡

做01背包做到的这个LIS,常见的n2会超时,所以才有nlogn可行

先来介绍一下n2

dp[i] 表示该序列以a[i]为结尾的最长上升子序列的长度

所以第一层循环循环数组a,第二层循环循环第i个元素前面的元素,里面做一个基本升序判断,然后找最大值

定义一个外部变量记录最大值

nlogn

用了一个数组进行维护对于每一个新加入的数,如果比这个数组中的所有元素都大,那么该数加入数组,如果有比这个数大的,则用该数替换第一个比他大的数

奈何这个题最坑的地方是输出!

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 5e5 + 5e3;
int dp[maxn],dp_idx;
struct node{
int p,r;
}data[maxn];
bool cmp(node a,node b)
{
return a.p < b.p;
}
int get_idx(int left,int right,int num)
{
while(left <= right)
{
int mid = (left + right) >> 1;
if(dp[mid] > num)right = mid - 1;
else left = mid + 1;
}
return right+1;
}
int main()
{
int n;
int cas = 1;
while(~scanf("%d",&n))
{
for(int i = 0;i < n;i++)
scanf("%d%d",&data[i].p,&data[i].r); //sort(data,data+n,cmp);不用排序,将无序的存储到有序的数组里就可以
// for(int i = 0;i < n;i++)
// printf("%d %d\n",data[i].p,data[i].r);
memset(dp,0,sizeof(dp));
dp[0] = data[0].r;
dp_idx = 0;
for(int i = 1;i < n;i++)
{
if(data[i].r > dp[dp_idx])
{
dp[++dp_idx] = data[i].r;
}
else
{
int idx = get_idx(0,dp_idx,data[i].r);
//cout<<"idx = "<<idx<<endl;
dp[idx] = data[i].r;
}
}
// for(int i = 0;i <= dp_idx;i++)
// {
// printf("%d\n",dp[i]);
// }
printf("Case %d:\nMy king, at most %d ",cas++,dp_idx+1);
if(dp_idx+1 > 1)
printf("roads can be built.\n\n");
else
printf("road can be built.\n\n");
}
return 0;
}