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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Luogu-P3205-HNOI2010-合唱队

發(fā)布時(shí)間:2024/4/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Luogu-P3205-HNOI2010-合唱队 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目地址

思路

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

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

首先進(jìn)行初始化,對(duì)于坐標(biāo)為i點(diǎn)的值t,處理如下:
他的左斷點(diǎn)為i,能合并出的值為t,右端點(diǎn)為i,值賦予i+1
為什么是i+1呢?因?yàn)槲覀冎蠛喜蓚€(gè)數(shù)的時(shí)候,從f[i][j]去搜,可以直接將其作為左端點(diǎn)搜索下一個(gè)數(shù)。

轉(zhuǎn)移方程為:
\[f[i][j]=f[i-1][f[i-1][j]]\]

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

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

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

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

假設(shè)數(shù)都是最大的40,可以得出2^x個(gè)數(shù)字可以合成最大的值為40+x。
又因?yàn)镹=262144,而且2^18=262144,所以最大的合成數(shù)為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:當(dāng)然,把數(shù)組開(kāi)反也是可以的。

轉(zhuǎn)載于:https://www.cnblogs.com/dmoransky/p/10742631.html

超強(qiáng)干貨來(lái)襲 云風(fēng)專(zhuān)訪(fǎng):近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。