codeforces1208 F. Bits And Pieces(SOS DP)
生活随笔
收集整理的這篇文章主要介紹了
codeforces1208 F. Bits And Pieces(SOS DP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
heyuhhh高維前綴和總結
SOS DP
SOS Dynamic Programming [Tutorial]
之前寫過相關的題目枚舉子集dp
枚舉子集
F[mask]=∑i∈maskA[i],i&mask=iF[mask]=\sum_{i\in mask}A[i],i\&mask=iF[mask]=i∈mask∑?A[i],i&mask=i
方法1,O(4n)O(4^n)O(4n)暴力枚舉
方法2,O(3n)O(3^n)O(3n)枚舉子集
for(int mask=0;mask<1<<N;mask++) {F[mask]=A[0];for(int i=mask;i;i=(i-1)&mask)F[mask]+=F[i]; }方法3,O(n×2n)O(n×2^n)O(n×2n)SOS dp
// 遞推版本 for(int mask=0;mask<1<<N;mask++) {dp[mask][-1]=A[mask];for(int i=0;i<N;i++){if(mask>>i&1) dp[mask][i]=dp[mask][i-1]+dp[mask^(1<<i)][i-1];elsedp[mask][i]=dp[mask][i-1];}F[mask]=dp[mask][N-1]; } // 不難發現第二維狀態可以滾動數組優化掉 for(int i=0;i<1<<N;i++) F[i]=A[i]; for(int i=0;i<N;i++)for(int mask=0;mask<1<<N;mask++)if(mask>>i&1)F[mask]+=F[mask^(1<<i)];F. Bits And Pieces
issue敲膩害題解
fmaskf_{\text{mask}}fmask?為mask\text{mask}mask的超集個數
iii是mask\text{mask}mask的超集說明mask&i=mask\text{mask}\&i=\text{mask}mask&i=mask
如果fmask≥2f_{\text{mask}}\ge 2fmask?≥2說明存在aj&ak=maska_j\&a_k=maskaj?&ak?=mask
從后往前枚舉aia_iai?維護aj&aka_j\&a_kaj?&ak?
超集個數只需要在加入aia_iai?時把它的所有子集個數加一即可。枚舉子集可以利用SOS DP優化。
貪心從高位往低位選擇即可。
#include<iostream> #include<algorithm> using namespace std; constexpr int N=2000010; int f[N],a[N],n; void add(int x,int bit) {if(f[x]>=2)return;if(bit<0) return f[x]++,void();add(x,bit-1);if(x>>bit&1) add(x^(1<<bit),bit-1); } int calc(int x) {int ans=0,tmp=0;for(int i=20;i>=0;i--){if(x>>i&1) ans+=1<<i;else{if(f[tmp+(1<<i)]>=2) tmp+=1<<i,ans+=1<<i;}}return ans; } int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n;for(int i=1;i<=n;i++) cin>>a[i];int ans=0;for(int i=n;i>=1;i--){if(i<=n-2) ans=max(ans,calc(a[i]));add(a[i],20);}cout<<ans<<'\n';return 0; }總結
以上是生活随笔為你收集整理的codeforces1208 F. Bits And Pieces(SOS DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 东北三宝分别是什么 东北三宝分别是啥
- 下一篇: 如何通过路由器查看宽带账号和密码怎么在路