24題 P2766最長不下降子串行問題

2022-02-23 21:14:45 字數 1466 閱讀 7472

網路流是個好東西,希望我也會。

網路流?\(orz\ zsy!!!!!\)

考慮我們是如何\(dp\)這個\(lis\)的。

我們是倒著推,設定\(dp(i)\)代表以\(i\)為起點的\(lis\)是多少。轉移太顯然了

\[dp(i)=max\+1,data[i]\le data[j]

\]想一想乙個合法的\(lis\)方案代表著什麼,代表著它是由這個式子乙個乙個推出來的。

考慮乙個數字只能用一次,那麼我們直接拆成兩個點\(v_0,v_1\)分別代表乙個數字的入度和出度,連一條\(v_1v_2,cap=1\)的邊。這樣就模擬了乙個數字可以被前面多個都相中但是只能往後面相中乙個的要求。

考慮如何構造方案,這個東西是個靈感,就是還原\(dp\) 轉移的過程,這樣就可以得到合法方案。

模型這樣建立

\[(i_0,i_1,1)

\\(s,i_0,inf),dp(i)=1

\\(i_1,t,inf),dp(k)=ans

\]這樣就好了。先咕咕咕。

#includeusing namespace std;typedef long long ll;

#define drp(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)

#define rp(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)

#define erp(t,a) for(register int t=head[a];t!=-1;t=e[t].nx)

#define midd register int mid=(l+r)>>1

#define tmp template < class ccf >

#define lef l,mid,pos<<1

#define rgt mid+1,r,pos<<1|1

#define pushup(pos) (seg[pos]=seg[pos<<1]+seg[pos<<1|1])

tmp inline ccf qr(ccf b)

tmp inline ccf max(ccf a,ccf b)

} }

return d[t]=data[t]&&dp[i]+1==dp[t]) add(id[t][1],id[i][0],1,1);

}rp(t,0,cnt) tmp[t]=e[t];

dinic(ans2);

rp(t,0,cnt) e[t]=tmp[t];

add(id[1][0],id[1][1],inf,1);

add(id[n][0],id[n][1],inf,1);

dinic(ans3);

if(ans1==1) ans2=ans3=n;

printf("%d\n%d\n%d\n",ans1,ans2,ans3);

return 0;

}

P2766 最長不下降子串行問題

話不多說,直接上思路。其實這就是一道dp動態規劃的經典問題,首先鏈上題目描述 問題描述 設有整數序列b1,b2,b3,bm,若存在 i1 i2 i3 in,且 bi1 bi2 bi3 bin,則稱b1,b2,b3,bm中有長度為n的不下降序列bi1,bi2,bi3,bin。求序列中最大不下降子串行長...

P2766 最長不下降子串行問題

問題描述 給定正整數序列x1,xn 1 計算其最長不下降子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的不下降子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的不下降子串行。程式設計任務 設計有效演算法完成 1 2 3 提出的計算任務。輸入...

P2766 最長不下降子串行問題

通俗的,對於每個數只能取一次和取無限次,將點拆開加入邊約束 因為讓求最長上公升子串行的個數,所以當乙個數字被選擇時,它必須是最長上公升子串行的一部分 我們求出最長上公升子串行的 dp 陣列,當 x 可以連邊 y 當且僅當 y 在 dp 中可以從 x 轉移過來 這樣問題就顯然了,我們只需要求解 dag...