【為了響應***勤節儉、反鋪張的精神,題目背景描述故事部分略去-】
給出一列數字,需要你新增任意多個逗號將其拆成若干個嚴格遞增的數。
如果有多組解,則輸出使得最後乙個數最小的同時,字典序最大的解(即先要滿足最後乙個數最小;如果有多組解,則使得第乙個數盡量大;如果仍有多組解,則使得第二個數盡量大,依次類推……)。
共一行,為初始的數字。
共一行,為拆分之後的數列。每個數之間用逗號分隔。行尾無逗號。
對於\(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...