[jzoj3252] 【GDOI三校聯考】炸彈(經典DP)
Problem
-
給出一個網格圖,由 構成,其中 相連,構成一顆樹.
-
可以放炸彈,一個炸彈可以覆蓋連續的一行 或一列 .
-
求放至少多少個炸彈,使得每個 都會被至少 個炸彈覆蓋。
Data constraint
Solution
-
資料範圍很小,加起來就 個點,很容易讓人誤入歧途.
-
正解實質上是DP
-
以從左到右,從上到下的順序找到第一個 ,作為根,依次走下去,形成一顆樹.
-
考慮每個格子 的狀態,不妨假設其父親格點是 :
- ①:直接在 這個點放了一個炸彈.
- ②:由 轉移過來,即 行放了炸彈,且能影響到 .
- ③:由 轉移過來,即在第 列放了炸彈,且能影響到 .
-
為何要把第二、三種分開討論?
-
顯然,這是因為 的影響不僅僅是 ,可能會影響到它父親,父親的父親……
-
所以,我們首先要把一個點的狀態給分析清楚,即可能有怎樣的決策影響.
-
分析好狀態,我們不難想到這樣的狀態設計:
- :表示以 為根的子樹,沒放炸彈,還剩一條與父親向同向的子樹鏈沒有炸.
- :表示以 為根的子樹,子樹炸完了,但沒有炸出去,即父親向的方向上沒有放炸彈.
- :表示以 為根的子樹,子樹炸完了,且炸出去了,即父親向的方向上有炸彈.
-
如此一來,我們便可以很方便的討論轉移了.
-
具體轉移分成四類,即有 個兒子時的情況.
-
這裡以 個兒子為例,其他是類似的,且 個兒子也是最複雜的。
不妨設目前轉移點編號為k
其中p[1],p[2],p[3]為k的3個兒子,且p[1]在父親向(上下)的方向上,p[2],p[3]在k點的左右方向上.
那麼必定有:
f[k][0] = min( Min(f[p[2]][0], f[p[2]][1], f[p[2]][2]) + f[p[3]][2],
Min(f[p[3]][0], f[p[3]][1], f[p[3]][2]) + f[p[2]][2]
) + f[p[1]][0];
//f[p[1]][0]是必須要轉移的,因為當前點沒放炸彈,如果要延續,則兒子必須連續
//因為當前點沒有放炸彈,所以“左右”方向上必定有一個是炸出去了的,也就是f[p[2]][2]或f[p[3]][2]必選一個
//另外一個則可以隨便選,所以是取3個min值.
f[k][1] = min( Min(f[p[2]][0], f[p[2]][1], f[p[2]][2]) + f[p[3]][2],
Min(f[p[3]][0], f[p[3]][1], f[p[3]][2]) + f[p[2]][2]
) + f[p[1]][1];
//f[p[1]][1]是必須要轉移的,因為當前點也不能放炸彈.
//其餘與上面一種情況完全類似.
f[k][2] = min( (1 + Min(f[p[1]][0], f[p[1]][1], f[p[1]][2]) +
Min(f[p[2]][0], f[p[2]][1], f[p[2]][2]) +
Min(f[p[3]][0], f[p[3]][1], f[p[3]][2])),
0 + f[p[1]][2] +
min( Min(f[p[2]][0], f[p[2]][1], f[p[2]][2]) + f[p[3]][2],
Min(f[p[3]][0], f[p[3]][1], f[p[3]][2]) + f[p[2]][2])
);
}
//這裡的轉移就分兩種情況討論了,即當前點放炸彈還是不放.
//看一看,應該還是很好理解的.
-
對於其餘的三種情況,其實也並不簡單多少,因為還要繼續分類討論,即有沒有上下的這種父親向的兒子.
-
總之,就是這樣的一個DP:
#include <cstdio>
#include <iostream>
#define F(i, a, b) for (int i = a; i <= b; i ++)
#define Min(a, b, c) ((a) < min(b, c) ? a : min(b, c))
#define num(a, b) ((a - 1) * m + b)
const int N = 51, M = 10 * N * N, dx[4] = {0, - 1, 1, 0}, dy[4] = {- 1, 0, 0, 1}, Impossible = 1e9;
using namespace std;
int n, m, tot, Sx, Sy, f[M][3]; char ch[N][N];
int tov[M], nex[M], las[M], Spe[M], Fa[M];
void ins(int x, int y, int z) {
tov[++ tot] = y, nex[tot] = las[x], las[x] = tot, Spe[tot] = z;
}
void Dfs(int k, int La) {
int SonTotal = 0, p[4]; p[0] = p[1] = p[2] = p[3] = 0;
for (int x = las[k] ; x ; x = nex[x])
if (tov[x] ^ La)
Fa[tov[x]] = Spe[x], Dfs(tov[x], k), p[++ SonTotal] = tov[x];
if (SonTotal == 0) {
f[k][0] = 0;
f[k][1] = Impossible;
f[k][2] = 1;
}
if (SonTotal == 1) {
if (Fa[p[1]] == Fa[k]) {
f[k][0] = min(f[p[1]][0], f[p[1]][1]);
f[k][1] = Impossible;
f[k][2] = min(min(f[p[1]][0], f[p[1]][1]) + 1, f[p[1]][2]);
}
else {
f[k][0] = f[p[1]][1];
f[k][1] = f[p[1]][2];
f[k][2] = Min(f[p[1]][0], f[p[1]][1], f[p[1]][2]) + 1;
}
}
if (SonTotal == 2) {
if (Fa[p[1]] == Fa[k] || Fa[p[2]] == Fa[k]) {
if (Fa[p[2]] == Fa[k]) swap(p[1], p[2]);
f[k][0] = min(f[p[2]][1], f[p[2]][2]) + f[p[1]][0];
f[k][1] = f[p[2]][2] + f[p[1]][1];
f[k][2] = min( (1 + Min(f[p[1]][0], f[p[1]][1], f[p[1]][
相關推薦
[jzoj3252] 【GDOI三校聯考】炸彈(經典DP)
Problem
給出一個網格圖,由
01
01
JZOJ 1005【GDOI2009五校聯考】公交網路【難】
這題還是有點難度的(像我這種caiji都能推出來的難度)
網上都沒題解 這題放在OJ上9年了都 才9個人做 (好吧是dalao們不想做)
於是經過本弱三天(一天一小時健康一輩子)的努力 把這題弄掉了QAQ
好了先放題目
Description
在世界某個安靜的角落,N 只毛毛
【平衡樹】2018國慶三校聯考D3T3
分析:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<assert.h>
#def
【資料結構】【線段樹】2018國慶三校聯考D5T3
題意:
分析:
有一個顯然的暴力方法: 對每個詢問,從左往右做一次,記錄字首和,當某個位置字首和為負後,則刪去當前點。再從右往左做一次。
考慮使這個過程變得高效: 可以將詢問按左端點從右往左排序,然後用棧依次處理每個在從左往右考慮時是否需要刪除。 再利用線段樹,求
【圖論】2018國慶三校聯考D5T2
分析:
題意非常醜陋。。。簡化出來就一句話:每個點有選中、未選中兩種狀態,現在給出一些矛盾關係,要求加入儘可能少的矛盾關係,使得沒有合法方案。
如此2sat的模型,顯然需要2sat的連邊方式。。。然後直接列舉每個位置選、不選是否合法即可。若不選合法,則考慮其練的邊是否有一個
【數論】2018國慶三校聯考D4T2
題意:
很簡單,給出正整數 n ,求出 n! 在十進位制表示下的從最末非零位開始的總共 k 位。
n
≤
【DP】三校聯考1017T3
題意:
分析:
考場上這題做了我兩個小時。。。果然第一步都錯了。。。 首先,所謂的絕對值其實可以用最優性忽略!!!! 即:|a-b|=max(a-b,b-a) 所以,不必考慮到底誰大誰小,在最優策略中,一定是合法的。
然後就很簡單了:每一個位置的貢獻分別可能為2,0,-
【DP】三校聯考1017T2
分析
非常水的np狀態轉移的題 定義
D
P
[
【莫隊】【連結串列】三校聯考1015T3
題意:
分析:
啊啊啊啊我發明的演算法居然以前有過。。。。https://blog.csdn.net/qq_34454069/article/details/80184286
方法其實很簡單。。。首先,把所有未加入的點放在一個雙向連結串列裡。
然後,每次插入一
【三校聯考10.24】點亮
@點亮@
@問題描述@
@分析1 - 隨機的性質@
@分析2 - 利用性質@
@演算法細節@
@程式碼@
@證明(過於枯燥)@
@[email protected]
@
【DP】2018國慶三校聯考
題意:
在N個格子之間,放入D-1個隔板(可以重合),要求每兩個相鄰隔板之間距離不超過M。求方案數。
N,M≤2000N,M\leq 2000N,M≤2000
D≤1012D\leq 10^{12}D≤
【DP】【概率與期望】2018國慶三校聯考D3T2
題意:
分析:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cma
【資料結構】【線段樹】【字串Hash】2018國慶三校聯考D4T3
題意:
分析:
題解見標籤
(不過這題有非正解方法可以卡過去。。我程式碼附在下面)
正解:
#include<cstdio>
#include<cstring>
#inclu
【組合數學】【DP】三校聯考 10.15 —— Chess
題目描述
dirty 在一個棋盤上放起了棋子。
棋盤規格為 n ∗ m,他希望任意一個 n ∗ n 的區域內都有 K 個棋子。dirty 很快就放置好了一
個滿足條件的棋盤方案,但是他認為這樣過於簡單了
【圖論】【DFS】三校聯考10.20T2
題意
尋找有多少條邊滿足:圖中所有奇環都包含這條邊,且這條邊不屬於任何偶環
分析:
最後一個性質好坑。。。一直在想那個性質結果T3都沒來得及做…
直接建一個DFS樹。因為是無向圖,所以只存在樹邊和返祖
【四校聯考】【比賽題解】FJ NOIP 四校聯考 2017 Round 7
快速 高度 str height size 都是 png logs h+ 此次比賽為廈門一中出題。都是聚勞,不敢恭維。
莫名爆了個0,究其原因,竟然是快讀炸了……很狗,很難受。
話不多說,來看看題:
【T1】
題意:
樣例:
PS:1<=h[i]<=1000
【九校聯考】鍛造
max -m i++ 預處理 csharp gin 怎麽 垃圾 getc 題目描述
“歡迎啊,老朋友。”
一陣寒暄過後,廠長帶他們參觀了廠子四周,並給他們講鍛造的流程。
“我們這裏的武器分成若幹的等級,等級越高武器就越厲害,並且對每一等級的武器都有兩種屬性值 b 和 c,但
【JZOJ3853】【NOIP2014八校聯考第2場第2試9.28】幫助Bsny(help)
EVRT
Bsny的書架亂成一團了,幫他一下吧!
他的書架上一共有n本書,我們定義混亂值是連續相同高度書本的段數。例如,如果書的高度是30,30,31,31,32,那麼混亂值為3;30,32,32,
【2017杭二聯考】 圖的有向環
tor gist fin lin def clu pro script space
P2555 - 【2017杭二聯考】圖的有向環
Description
題目背景: 幻想鄉的亡靈公主,西行寺幽幽子,在幻想鄉很受歡迎,經常有妖怪來拜訪她,但是幽 幽子並不喜歡被打擾
NOIP2018三校聯考--電壓機制(voltage)
很容易發現與奇環和偶環有關,但是仔細想清楚和怎麼用程式實現還是很難的
但是我們dfs一邊後,會發現能形成環的邊都變成了返祖邊
而且這些返祖邊對於答案大部分情況下都沒有貢獻
偶環上的邊都不能做出貢獻,當且僅當一條邊被所有奇環包含時才能做出貢獻
有兩個性質