嘟嘟嘟
這道題可以說是[hnoi2003]消防局的設立的公升級版。距離從2改為了d。
辛虧d只有20,這也就是乙個切入點。
令f[u][j]表示u四周 j - 1的距離需要被覆蓋,g[u][j]表示u可以像四周覆蓋 j 的距離。
考慮轉移方程,令v為u的其中乙個兒子:
1.f[u][j]:直接從v延伸而來:f[u][j] = σ f[v][j - 1]。
2.g[u][j]:用前幾個兒子已經得出的g[u][j]去覆蓋v:g[u][j] = g[u][j] + f[v][j];或者用v覆蓋u:g[now][j] = f[now][j +1] +g[v][j + 1],所以g[now][j] = min.
對於f,可能距離小的比大的還優,所以還要再求一遍字首最小值:f[now][j] = min (0 <= k < j)
同理對於g,可能覆蓋距離大的比距離小的還優,所以字尾最小值:g[now][j] = min (j < k <= d)
最後考慮的是初值:顯然g[now][j] = c[now] (1 <= j <= d)。然後如果這個點b神可能出現,f[now][0] = g[now][0] = c[now],表示這個點需要覆蓋。
(**摺疊壞啦)
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11using
namespace
std;
12#define enter puts("")
13#define space putchar(' ')
14#define mem(a, x) memset(a, x, sizeof(a))
15#define rg register
16 typedef long
long
ll;17 typedef double
db;18
const
int inf = 0x3f3f3f3f;19
const db eps = 1e-8;20
const
int maxn = 5e5 + 5;21
inline ll read()
2226
while(isdigit(ch))
27if(last == '
-') ans = -ans;
28return
ans;29}
30 inline void
write(ll x)
3136
37int
n, d, m, c[maxn];
38bool
vis[maxn];
3940
struct
edge
41e[maxn << 1
];44
int head[maxn], ecnt = -1;45
void addedge(int x, int
y)46
;48 head[x] =ecnt;49}
5051
int f[maxn][22], g[maxn][22
];52
void dfs(int now, int
_f)5368}
6970
intmain()
7177
for(int i = 1; i < n; ++i)
7882 dfs(1, 0
);83 write(f[1][0
]), enter;
84return0;
85 }
SHOI2016 隨機序列
給你乙個數列,在相鄰兩個數之間插入加號,減號或乘號 每次支援單點修改,求所有這樣可以得到的表示式之和,膜1e9 7 sol 我是個 sb 可以發現,如果某位置出現了加號,後面一定有乙個減號把它消掉,於是答案就是一些出現了好幾次的字首積之和 算一下每段字首積的貢獻即可 include define i...
Bzoj3562 神器化合物 Shoi 2014
ac通道 分析 若把每乙個原子看作乙個節點,將化學鍵看作一條邊,那麼這個題目要求的 分子的個數 很容易就可以看出是求圖中聯通塊的個數。求聯通塊的個數,可以使用並查集。可如何求出每一步的聯通塊的個數呢?可以知道,當連上一條邊時,若此邊連線的是兩個不同的聯通塊,那麼分子個數就會減一 當刪去一條邊時,若刪...
BZOJ 4597 Shoi2016 隨機序列
很可做的一道題 考慮一下一段序列的答案為b x,x為最右連續一段是乘積,然後和為x,b則為對應的左邊的和 然後考慮在右邊加乙個數k,分類討論一下發現x kx,b 2x 3b 於是就可以dp了 然後dp可以矩陣轉移 於是就可以用線段樹維護矩陣 就水過去了 好像很簡單哎,ac率好高的說 include ...