日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Luogu-P3205-HNOI2010-合唱队

發布時間:2024/4/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Luogu-P3205-HNOI2010-合唱队 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目地址

思路

這道題其實是P3146 [USACO16OPEN]248的升級版,但是N的范圍很大,為262144。原先的O(N^3)的方法自然會TLE,甚至O(N^2)的方法也不足以解決。

定義f[i][j]為從左端點j開始,能合并出i的(右端點值+1)的值

首先進行初始化,對于坐標為i點的值t,處理如下:
他的左斷點為i,能合并出的值為t,右端點為i,值賦予i+1
為什么是i+1呢?因為我們之后合并兩個數的時候,從f[i][j]去搜,可以直接將其作為左端點搜索下一個數。

轉移方程為:
\[f[i][j]=f[i-1][f[i-1][j]]\]

為什么?
\(f[i-1][j]\)代表從端點j開始找能合并成i-1的最少距離,并找出右端點的下一個端點。
\(f[i-1][f[i-1][j]]\)就代表從上一個找到的右端點下個端點開始搜索。如果沒有搜到,肯定返回時0,就說明沒有找到。

所以,如果當\(f[i][j]\)不為0后,這個i就是最大合并的值。

所以我們只要枚舉i與j就可以了。
j的范圍是n,那i呢?

我們知道,數最大是40,兩個40合成一個41,四個40合成一個42,八個40合成一個43,十六個40合成一個44。

假設數都是最大的40,可以得出2^x個數字可以合成最大的值為40+x。
又因為N=262144,而且2^18=262144,所以最大的合成數為40+18=58,我們只要枚舉到58就行了。

代碼示例

#include<cstdio> using namespace std; int f[61][262145],n,x,ans; int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&x),f[x][i]=i+1;for(int i=2;i<=58;i++){for(int j=1;j<=n;j++){if(!f[i][j])f[i][j]=f[i-1][f[i-1][j]];if(f[i][j])ans=i;}}printf("%d",ans);return 0; }

PS:當然,把數組開反也是可以的。

轉載于:https://www.cnblogs.com/dmoransky/p/10742631.html

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的Luogu-P3205-HNOI2010-合唱队的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。