0x57 倍增優化DP

2022-04-29 23:42:12 字數 2895 閱讀 6687

真的是下定了巨大的決心來搞這一講,果不其然耗了一晚上

開車旅行(真的是noip的題嗎怎麼這麼恐怖)

首先,先用set把小a和小b從城市i出發,到達的下乙個城市預處理出來。

f[i][j][k]表示走了2^i天,j城市出發,k表示誰開車,到達那個城市。

轉移就是f[i][j][k]=f[i-1][f[i-1][j][k]][k] 相信很好理解

特別的i-1==0時,因為k是奇數,開車的人是變化的,所以f[i][j][k]=f[i-1][f[i-1][j][k]][k^1]

令da[i][j][k],db[i][j][k],分別表示小a和小b這個狀態下走的路程

對於詢問1,列舉所有的城市作為起點,然後基於二進位制劃分的思想,倒著for一步步在滿足走的總路程<=x0的情況下前進,這樣可以計算出小a走的路程和小b走的路程。找最大比值即可。

詢問二就直接詢問小a走的路程和小b走的路程了。同理可求。

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;int h[110000

];struct

snode

snode(

int id,int h)

friend

bool

operator

};set

s;set

::iterator it,lt,rt;

int g[110000

],i;

bool cmp(int g1,int g2)

int ago[110000],bgo[110000

];int f[22][110000][2]; ll da[22][110000][2],db[22][110000][2

];ll a,b;

void solve(int now,int

x0)}

intmain()

rt++;

if(rt!=s.end())

i=i;sort(g+1,g+m+1

,cmp);

if(m>1)ago[i]=g[2

];

if(m>0)bgo[i]=g[1

]; }

memset(f,

0,sizeof

(f));

for(int i=1;i<=n;i++)

for(int i=1;i<=20;i++)

for(int j=1;j<=n;j++)

for(int k=0;k<=1;k++)

}int x0,ans;ll ansa=1,ansb=0

; scanf("%d

",&x0);

for(int i=1;i<=n;i++)

printf(

"%d\n

",ans);

intq,x,y;

scanf("%d

",&q);

while(q--)

return0;

}

開車旅行

count the repetitions

f[j][i]表示從s1第i個字元開始,能夠表示出s2 2^j最少需要多少字元。

就有f[j][i]=f[j-1][i]+f[j-1][((i+f[j-1][i])-1)%s1len+1]

最後就列舉匹配的起始點,同樣在不超過s1len*n1的情況下用二進位制一步步跳,記錄當前起始點的最優解更新答案就好了。

#include#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;

char s1[110],s2[110

];ll f[

40][110

];int

main()

')break

; scanf(

"%d%s%d

",&n2,s1+1,&n1);

int s2len=strlen(s2+1),s1len=strlen(s1+1

);

bool bk=false

;

for(int i=1;i<=s1len;i++)

}p=p%s1len+1

; f[

0][i]+=cc+1

;

if(bk==true)break

; }

if(bk==true)break

; }

if(bk==true)continue

;

for(int j=1;j<=30;j++)

for(int i=1;i<=s1len;i++)

f[j][i]=f[j-1][i]+f[j-1][((i+f[j-1][i])-1)%s1len+1

];

ll m=0

;

for(int i=1;i<=s1len;i++)

printf(

"%lld\n

",m/n2);

}return0;

}

count the repetitions

好像都是先預處理出下一步的狀態,然後二進位制劃分啊