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