#345 Div2 B. Beautiful Paintings

第一次在CSDN上寫博客,紀念一下。

題意:1<=N<=1000大小的1<=ai<=1000的數組,最多有多少對滿足a(i+1)>ai;即嚴格上升的順序

鏈接:http://codeforces.com/contest/651/problem/B

這道題 virtual 的時候過了,不過做這道題用的時間用了比較久,手速慢。賽完後看了一下帆神的代碼,竟然辣麼短,而且不理解什麼意思,百度了一下其他題解才弄明白

我的方法:每次循環都產生出一個嚴格上升的序列,把序列的長度加到答案上,然後把此序列中的數在原序列中刪除,重複操作遍歷原數列所有數後的ans即最優解,最壞的時間複雜度O(n^2*logn)(循環n次,每次快排n*logn)

更好的方法:上述方法中每次找到第K個嚴格上升的序列加到遍歷過的K-1序列之後的ans就是(n-1)-K,因爲每次生成一個序列就和前面的序列斷開了一個,一共有n-1個間隔,所以最優解即找到max(數組中出現次數最多的數出現的次數),然後(n-1)-max即可,複雜度爲O(n*logn)(快排之後做)或者O(n)(開數組num[a]記錄數字a出現的次數,當a的範圍過大時會超內存而不適用,此題a<=1000,可以用)

我的代碼:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

using namespace std;

int n;
int cnt;
int ma[1010];
int ans;

int cmp(const void*a,const void*b){
    return *(int*)b-*(int*)a;
}

int main()
{
    int i,j;
    int tmp;
    int flag;
    while(~scanf("%d",&n)){
        memset(ma,0,sizeof(ma));
        for(i=1;i<=n;i++){
            scanf("%d",&ma[i]);
        }
        ans=0;cnt=n;
        while(cnt>0){
            qsort(ma+1,n,sizeof(ma[0]),cmp);
            tmp=0;
            flag=-1;
            for(i=1;i<cnt;i++){
                if(ma[i]!=ma[i+1]){
                    tmp++;
                    ma[i]=0;
                    flag=i+1;
                }
                else
                    ;
            }
            if(flag!=-1)
                ma[flag]=0;
            ans+=tmp;
            cnt-=tmp+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
O(n*logn)代碼

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define N 100010
using namespace std;
int a[N];
int n;
int main()
{
    int i;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    sort(a,a+n);
    int ans=0,tmp=0;
    for(i=1;i<=n;i++)
    {
        while(i<=n&&a[i]==a[i-1])
        {ans++;i++;}
        tmp=max(tmp,ans);
        ans=0;
    }
    ans=n-1-tmp;
    printf("%d\n",ans);

    return 0;
}
O(n)代碼

#include <cmath>  
#include <string>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <iostream>  
#include <algorithm>  
using namespace std;  
#define maxn 1005  
inline int mini(int a, int b)  
{  
    return a < b ? a : b;  
}  
inline int maxi(int a, int b)  
{  
    return a > b ? a : b;  
}  
int num[maxn];  
int main()  
{  
    int n, t, m = -1, ans = 0;  
    scanf("%d", &n);  
    for (int i = 0; i < n; ++i)  
    {  
        scanf("%d", &t);  
        num[t]++;  
    }  
    for (int i = 1; i < maxn; ++i)  
        m = maxi(m, num[i]);  
    ans = n - m;  
    printf("%d\n", ans);  
    return 0;  
}  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章