1. 程式人生 > 其它 >AtCoder DP Contest 26題

AtCoder DP Contest 26題

部分內容

E-Knapsack2(揹包dp)

容量w資料太大,dp陣列改為f[v]即價值為v時的最小重量

轉移方程f[j]=min(f[j],f[j-v[i]]+w[i])

F-LCS(最長公共子序列字串版)

f[i][j]為兩字串前i、j個的最長公共子序列

並用book陣列標記,book[i][j]=0表示狀態由f[i-1][j]轉移過來

book[i][j]=1表示狀態由f[i][j-1]轉移過來

book[i][j]=2表示第i、j個可以匹配,由f[i-1][j-1]轉移過來

作用是dfs得到答案字串

G-Longest Path(非dp)

鏈前存圖,順便統計個數入度

從沒有入度的點開始遍歷,佇列實現

遍歷過的入度減1,無入度時存入佇列,此時該點已找到最大值

I - Coins(概率dp)

記f[i][j]為擲i次,j次向上的概率

則有f[i][j]=f[i-1][j-1]*p[i]+f[i-1][j]*(1.0-p[i]);

J - Sushi

在DFS中設a為1個盤子的數量,b為2個的數量,c為3個

最後一次一定是a=1,b=0,c=0

由該狀態遞推,每一次操作期望為(總運算元/有效運算元)

double tot=0;
    if(a) tot+=dfs(a-1,b,c)*(1.0*a/(a+b+c));
    if(b) tot+=dfs(a+1,b-1,c)*(1.0*b/(a+b+c));
    if(c) tot+=dfs(a,b+1,c-1)*(1.0*c/(a+b+c));
    tot=tot+1.0*n/(a+b+c);
    return f[a][b][c]=tot;

K - Stones(博弈論)

給出n種取法a[i],k為上限,先不能取的人就輸,t=0即以A為主觀,1即以B為主觀

從結果k往前推,以先取的人(A)為主觀

將k-a[i]能夠到的數字記為後取的人(B)的必勝點

如果B達不到,則A能勝

所以再往前A要達到讓B不能達到的點

以此類推

if(k>=a[i]&&!dfs(k-a[i],!t))

{xx=true;}

L-Deque(絕世dp)

題目要求在a陣列雙端不斷取數,Taro取值總和為X,Jiro取值總和為Y

Taro試圖最大化X-Y,Jiro最小化X-Y

則兩人都想取儘可能大的數

將Jiro轉變為最大化Y-X

上一個人取的最大值在下一個狀態變成相反數

就有f[l][r]=max(a[l]-f[l+1][r],a[r]-f[l][r-1])

M-Candies

統計糖果分配方法個數,每人取值上限為a[i]

f[i][j]為前i個人已經分了j顆糖的方案數

遍歷過後把f[i][j]變為f[i][1-j]的字首和,方便計算

方程f[i][j]=f[i-1][j]-f[i-1][j-a[i]-1]

N - Slimes

常規區間dp,

在每一對l和r中間列舉斷點求最值

O - Matching(狀壓dp)

寫個for(inti=0;i<(1<<n);++i)在外面表示男生匹配的狀態

設f[s]表示匹配好的女生的狀態為s(二進位制表示s)

if(m[num][j]==1&&((1<<j)^i)!=i)可以配對但還沒轉移=>f[(1<<j)^i]=(f[(1<<j)^i]+f[i])%Mod;

Q - Flowers(上升子序列附加值)

對於每個i有高度h[i]和值a[i],設f[i]表示1-i的上升子序列最大值

以h[i]為下標存入樹狀陣列,每更新一個i先求出f[i]=a[i]+max(pre[h[1~i]])

之後在update(h[i],f[i])

ans=max(f[i])

R - Walk(矩陣乘法)