Luogu-P3205-HNOI2010-合唱队
題目地址
思路
這道題其實(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)題。
- 上一篇: 自定义用户环境
- 下一篇: 2.5 Hive中外部表的讲解