Codeforces 1017 CThe Phone Number

Radiumm發表於2018-08-09

題意:給了數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;
}

 

相關文章