常州集訓難題選解

2021-07-22 11:59:44 字數 1478 閱讀 9678

8.10 t6(bzoj1727):

題意:n(1 <= n <= 25000)道工序,每道工序有兩步,必須做完第一步才能做第二步,給出每步的時間,求最小完成時間。

分析:先說乙個錯誤解法:

對於兩道工序a,b,a要放在b前當max(a1+b1+b2, a1+a2+b2) < max(a2+b1+b2, a1+a2+b1),即min(a1, b2) < min(a2, b1),所以按照這個排序就好。

這樣做的錯誤是沒有考慮到之前工序對a,b的影響。

雖然bzoj上能a,這裡給個錯誤資料:

108 10

1 43 4

1 15 10

1 71 9

10 9

5 45 2

答案是61,而以上那種做法是64。

網上題解都是這麼寫的,經我一一查證,全錯。

下面說正確解法:

正確解法也是貪心,排序方法是先把a < b的排在前頭,內部按a從小到大排序,然後放a = b的,內部順序隨意,最後放a > b的,內部按b從大到小排序。

證明方法就是交換相鄰元素法,考慮之前工序的影響,分類較多,不詳細證明了。

8.11 t3:

一棵n(n <= 100000)個點的樹,可去掉一條邊,求**出的兩個子樹的直徑和的最大值。

分析:一道比較難的樹形dp,比較重要的是定義狀態。

我們觀察到,去掉一條邊後,下面的子樹直徑可以輕鬆求出,上面的東西我們需要求出乙個陣列mx(i),表示去掉i和他父親的邊之後,上面的子樹的直徑,所以整道題的關鍵就是求mx陣列。

為了方便,我們將x的父親設為f.

首先考慮經過f的,我們需要處理出每個點向下走的最長,次長,第三長鏈d1, d2, d3,和強制向上走一步,再往下走的最長路up。

然後是不經過f的,我們需要處理出每個點的直徑和次長直徑,再跟f的父親的mx值取max.

然後遞推很簡單,兩遍dfs就行了。

#include #include using namespace std;

typedef long long ll;

const int n = 100005, m = 200005;

int n,x,y,z,e=1,f[n],hd[n],nxt[m],to[m],w[m];

ll ans,up[n],mx[n];

struct nd d1[n],d2[n],d3[n],s1[n],s2[n];

void add(int x, int y, int z)

void dfs(int x, int fa)

}void dfs2(int x, int fa)

mx[to[i]] = max(mx[to[i]], max(up[x], mx[x]));

dfs2(to[i], x); }}

int main()

printf("%lld", ans);

return 0;

}

(未完待續)

雅禮集訓Day3 難題選講

這道題很顯然是個最小割,u,v,w 代表邊 我當時想到的程度是 先將棋盤黑白染色,白左黑右,x表示白,y表示黑。s,x1,花費 x1,x2,代價 x2,y2,inf y2,y1,代價 y1,t,花費 然後就不知道該怎樣下去了,發現題解多建了條 x1,y1,inf 恩,挺妙的,認真yy下,這條邊保證了...

matlab集訓九(解插值問題)

一維插值 yi interp1 x,y,xi,method 其中method指定的方法為nearest,linear,spline,cubic,pchip 分段三次 hermite 插值 所有的插值方法都要求 x 是單調的。x 與 y 是具有相同大小 的向量,求在 xi 點處的插值函式值 yi yi...

面對電車難題,自動駕駛會怎麼選?

什麼是電車難題?一輛剎車失靈的有軌電車正在急速行駛,前面的鐵軌上綁著一群人,如果任由電車行駛,那群人必將罹難。這時你站在鐵軌正上方的天橋上,你前面有乙個胖子,你可以將他推下天橋以阻擋住電車來營救那群人,不過這個胖子會遇難。當然,你考慮過自己跳下去,但由於你自己的體積太小而無法阻擋電車,這個方案並不可...