Codeforces 1017 CThe Phone Number

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhlbjtu2016/article/details/81534626

题意:给了数n代表数列的长度,要求构造一个数列使得最长上升自序列的长度和最长下降子序列的长度和最小

分析:  构造.我们把这个序列分成若干段,首先满足最长上升子序列的长度最小的话,就尽可能让每一段是递减的,而最长上升子序列的长度和子段有关.  再考虑最长下降子序列,因为已经每一段之间都是递减的关系,那么子段递增才可能尽可能让递减序列的长度小.  至于分成多少段,我们假设分成x段,则最长上升子序列的长度为n/x,最长下降子序列的长度为x,我们要使得x+n/x尽可能小就是x=sqrt(n)的时候

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn],tmp[maxn];
vector<int>vec[maxn];
bool cmp(int x,int y)
{
    return x > y;
}
int main()
{
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++)
        a[i] = i;
    int x = (int)sqrt(n);
    //printf("%d\n",x);
    int r = n % x;
    int d = n / x;
    if(r != 0)d++;
    for(int i = 1; i <= d; i ++)
    {
        for(int j = (i - 1) * d + 1; j <= i * d && j <= n; j++)
            vec[i].push_back(a[j]);
    }
    for(int i = d; i >= 1; i--)
    {
        for(int j = 0; j < vec[i].size(); j++)
            printf("%d ",vec[i][j]);
    }
    printf("\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhlbjtu2016/article/details/81534626