HAOI2006 數字序列

2022-05-11 00:50:02 字數 1290 閱讀 5340

現在我們有乙個長度為n的整數序列a。但是它太不好看了,於是我們希望把它變成乙個單調嚴格上公升的序列。但是不希望改變過多的數,也不希望改變的幅度太大。

輸入格式:

第一行包含乙個數n,接下來n個整數按順序描述每一項的鍵值。

輸出格式:

第一行乙個整數表示最少需要改變多少個數。

第二行乙個整數,表示在改變的數最少的情況下,每個數改變的絕對值之和的最小值。

輸入樣例#1: 

4

5 2 3 5

輸出樣例#1: 14

思路:

一道   題

(1)第一問

假設第i,j(i=j-i

移項發現a[j]-j>=a[i]-i

隨後我們將每個a[i]-=i,然後去求a的最長不下降序列長度即可,用總長度n減去這個長度就是答案

最長不下降序列很顯然要用nlogn的時間複雜度去搞

(2)第二問

設f[i]為前i為為嚴格公升序序列的最小代價

有乙個結論,就是區間(i,j)變為公升序序列的最小代價為在(i,j)之間找乙個k,

將a[i~k] 都變成a[i],將a[k+1~j] 都變成a[j],這之間的最小值就是這個區間內的最優代價

證明然後直接暴力即可

理論實踐複雜度為o(n^3),但是由於第二重迴圈在隨機資料項可能什麼都沒有,所以實際複雜度應遠小於o(n^3)

#include#include#include#include#include#define inf 19999999999;

#define int long long

#define rep(i,a,b) for(int i=a;i<=b;i++)

#define yx(k,x) for(int k=fir[x];k;k=nxt[k])

using namespace std;

int dp[36000],c[36000],a[36000],n,len,f[36000],sum1[36000],sum2[36000],fir[36000],nxt[36000],to[36000],tot;

void ade(int x,int y)

signed main()c[0]=-inf;len=1,c[1]=a[1];dp[1]=1;

rep(i,2,n)

rep(i,0,n)f[0]=0;

rep(i,1,n)

}printf("%lld\n%lld",n-dp[n],f[n]);

return 0;

}

HAOI2006 數字序列

現在我們有乙個長度為n的整數序列a。但是它太不好看了,於是我們希望把它變成乙個單調嚴格上公升的序列。但是不希望改變過多的數,也不希望改變的幅度太大。輸入格式 第一行包含乙個數n,接下來n個整數按順序描述每一項的鍵值。輸出格式 第一行乙個整數表示最少需要改變多少個數。第二行乙個整數,表示在改變的數最少...

HAOI2006 數字序列 題解

題目鏈結 現在我們有乙個長度為 n的整數序列 a。但是它太不好看了,於是我們希望把它變成乙個單調嚴格上公升的序列。但是不希望改變過多的數,也不希望改變的幅度太大。第一行是乙個整數,表示序列長度 n。第二行有 n個整數,第 i個整數表示序列的第 i項 ai 第一行輸出乙個整數,表示最少需要改變多少個數...

HAOI2006 數字序列 dp,二分

現在我們有乙個長度為n的整數序列a。但是它太不好看了,於是我們希望把它變成乙個單調嚴格上公升的序列。但是不希望改變過多的數,也不希望改變的幅度太大。求在改變的數最少的情況下,每個數改變的絕對值之和的最小值。n leq 35000 保證資料隨機 第一問很容易,只需要令 b i a i i 然後跑最長不...