洛谷 P1415 拆分數列 解題報告

2022-04-30 02:45:11 字數 1209 閱讀 9169

【為了響應***勤節儉、反鋪張的精神,題目背景描述故事部分略去-】

給出一列數字,需要你新增任意多個逗號將其拆成若干個嚴格遞增的數。

如果有多組解,則輸出使得最後乙個數最小的同時,字典序最大的解(即先要滿足最後乙個數最小;如果有多組解,則使得第乙個數盡量大;如果仍有多組解,則使得第二個數盡量大,依次類推……)。

共一行,為初始的數字。

共一行,為拆分之後的數列。每個數之間用逗號分隔。行尾無逗號。

對於\(10\%\)的資料,輸入長度\(\le5\)

對於\(30\%\)的資料,輸入長度\(\le15\)

對於\(50\%\)的資料,輸入長度\(\le50\)

對於\(100\%\)的資料,輸入長度\(\le500\)

這個題還挺巧妙的。

發現要求是字典序構造,而且兩組要求看起來不太一樣。

考慮分開做,先在保證有解的情況下找到最後乙個最小的數。

令\(dp_i\)代表以\(i\)為結束時的字串的最大字首位置(即滿足最後一位最小),這樣我們每次找的都是最小的位,具有最優子結構性質。

轉移:\(num_\)代表從\(i\)到\(j\)的數字大小

注意比較的複雜度,所以總體是\(o(n^3)\)的,不過上界非常松

然後我們再反著做一遍類似的\(dp\),發現還是由最大字首推了最大字首的,所以剛好滿足了要求\(2\)

注意前導\(0\)的一些特判

code:

#include #include const int n=502;

int n,dp[n];

char s[n];

bool check(int l1,int r1,int l2,int r2)//前是否大於後

int main()

int d=dp[n],pos=dp[n];

memset(dp,0,sizeof(dp));

dp[pos]=n;

while(s[pos-1]=='0') --pos,dp[pos]=n;

for(int i=pos-1;i;i--)

for(int j=d;j>=i;j--)

if(check(j+1,dp[j+1],i,j))

for(int l=1,r;l<=n;l=r+1)

return 0;

}

2018.10.21

洛谷P1415 拆分數列 解題思路

因為某些申必原因被刪除 題目描述 給出一列數字,需要你新增任意多個逗號將其拆成若干個嚴格遞增的數。如果有多組解,則輸出使得最後乙個數最小的同時,字典序最大的解 即先要滿足最後乙個數最小 如果有多組解,則使得第乙個數盡量大 如果仍有多組解,則使得第二個數盡量大,依次類推 輸入輸出格式 輸入格式 共一行...

P1415 拆分數列(記憶化搜尋)

這麼麻煩的題敲出來沒wa真的是舒服 原題 題意 給出一列數字,需要你新增任意多個逗號將其拆成若干個嚴格遞增的數。如果有多組解,則輸出使得最後乙個數最小的同時,字典序最大的解 即先要滿足最後乙個數最小 如果有多組解,則使得第乙個數盡量大 如果仍有多組解,則使得第二個數盡量大,依次類推 解析 大小比較函...

洛谷1062 數列 解題報告

給定乙個正整數k 3 k 15 把所有k的方冪及所有有限個互不相等的k的方冪之和構成乙個遞增的序列,例如,當k 3時,這個序列是 1,3,4,9,10,12,13,該序列實際上就是 3 0,3 1,3 0 3 1,3 2,3 0 3 2,3 1 3 2,3 0 3 1 3 2,請你求出這個序列的第n...