JLOI2015 戰爭排程 解題報告

2022-04-29 21:45:16 字數 1224 閱讀 6491

感覺一到晚上大腦就宕機了...

題目本身不難,就算沒接觸過想想也是可以想到的

這個滿二叉樹的深度很淺啊,每個點只會和它的\(n-1\)個祖先匹配啊

於是可以暴力列舉祖先鏈的選擇

然後處理某個點\(i\)時,已經列舉了\(i\)到根的祖先的選擇

這時候我們發現列舉\(i\)後,左右兒子的貢獻的獨立的,然後左右兒子的選擇對上面是沒有影響的

可以直接設\(dp_\)表示\(i\)子樹\(j\)黑點的最大值

然後直接子樹合併兩個兒子就可以了

複雜度?

\(t(n)=2(2t(n-1)+2^n)\)

好像是這個,化出來差不多是\(o(n2^)\)

code:

#include #include #include using std::max;

template void read(t &x)

#define ls id<<1

#define rs id<<1|1

const int n=1<<10;

int dp[n][n],w[n][n],f[n][n],cho[n],n,m;

void dfs(int id,int k)

return;

} cho[id]=0;

dfs(ls,k>>1),dfs(rs,k>>1);

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

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

dp[id][i+j]=max(dp[id][i+j],dp[ls][i]+dp[rs][j]);

cho[id]=1;//w[i][j]

dfs(ls,k>>1),dfs(rs,k>>1);

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

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

dp[id][i+j]=max(dp[id][i+j],dp[ls][i]+dp[rs][j]);

}int main()

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

dfs(1,k);

int ans=0;

for(int i=0;i<=m;i++) ans=max(ans,dp[1][i]);

printf("%d\n",ans);

return 0;

}

2019.2.25

JLOI2015 戰爭排程

記憶體限制 256 mib 時間限制 1000 ms 標準輸入輸出 題目型別 傳統 評測方式 文字比較 臉哥最近來到了乙個神奇的王國,王國裡的公民每個公民有兩個下屬或者沒有下屬,這種關係剛好組成乙個 n 層的完全二叉樹。公民 i 的下屬是 2i 和 2i 1 最下層的公民即葉子節點的公民是平民,平民...

JLOI2015 戰爭排程 war

一開始看這題,毫無頭緒 不過發現n十分的小,最多只有10,想一想暴搜加優化。先試著打了打暴搜,從上往下列舉狀態,然後搜尋到子節點的時候,再統計答案,每個父節點的答案是兩個子節點答案的和,dfs x,y,z 表示當前搜到的點二進位制狀態為x,從根節點到底層打仗的狀態為y,然後此時要打仗的人有z個。然後...

題解 JLOI2015戰爭排程

搜尋 狀壓 dp。注意到乙個性質 考慮一棵以x為根的子樹,在x到原樹的根的路徑上的點如果都已經確定了方案,那麼x的左右兒子的決策就彼此獨立,互不影響了。所以我們考慮狀壓一條路徑上每一層節點的狀態,求出dp u x 以u為根的子樹中分配x個作戰平民的最大收益是多少 注意因為是在dfs當中,所以dp陣列...