原題連結
思路 + 演算法
首先,考慮讀入到 \(a_i\) 時,如果要得到此時的最優解(指所有牛的編號不重不漏地覆蓋 \([1,i]\) 的所有編號),對於第 \(i\) 頭奶牛,因為在它前面有 \(a_i\) 頭奶牛的編號小於它,所以第 \(i\) 頭奶牛的編號應當為 \(a_i+1\)。
如果有一頭新的奶牛 \(i+1\) 加入到這個奶牛序列,要使它的編號恰好為 \(a_{i+1}+1\),原來編號為 \(a_{i+1}+1\) 的奶牛就必須讓編號 \(+1\) 來讓出這個編號。同樣,編號大於 \(a_{i+1}+1\) 的奶牛也必須跟著增加編號來維持前 \(i\) 頭奶牛之間的相對關係。
那麼我們的暴力演算法就出現了:
每讀入一個新的 \(\bf{a_i}\),就讓它之前編號大於等於 \(\bf{a_i}\) 的奶牛的編號增加 \(\bf{1}\),最後再將第 \(\bf{i}\) 頭奶牛的編號設定為 \(\bf{a_i+1}\)。
最後輸出所有奶牛的編號即可,注意第一頭奶牛的編號要在輸入前初始化為 \(1\)。
時間複雜度 \(O(N^2)\)。
AC 程式碼
#include<cstdio>
using namespace std;
const int N=1e5+5;
int n,a[N],ans[N];
int main()
{
scanf("%d",&n);
ans[1]=1;
for(int i=2;i<=n;i++)
{
scanf("%d",&a[i]);
for(int j=1;j<i;j++)
if(ans[j]>a[i]) ans[j]++;
ans[i]=a[i]+1;
}
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}