也許是乙個常見套路,然而我並不會...
考慮這個\(2 \times n\)的格仔形成的樹的結構
任意相鄰的兩列都有一條邊或者兩條邊,稱兩條邊的相鄰兩列為聯通,聯通具有傳遞性。
性質:在乙個聯通列中,有且僅有一條豎邊
於是可以按聯通性進行劃分進而dp
比如這個圖就劃分出了5個聯通塊
對於這個題,首先按邊統計貢獻,每個邊貢獻為\(sum(sum-x)\),\(sum\)是總點權,\(x\)是這個邊任意一側的點權和。
然後做dp就好了,\(dp_\)表示\(i\)與\(i+1\)列只連一條邊的最小價值
\[dp_=\min_ (dp_+cost(m,n,bl,br))
\]後面的\(cost\)隨便\(o(n)\)算一算就好了
code:
#include #include #include #include #include #include #define ll long long
using std::min;
const int n=52;
template void read(t &x)
ll a[2][n],fl[n],fr[n],sum,dp[n][2];
ll cost(int n,int br,int m,int bl)
a[bl][m]+=fl[m-1];
a[br][n]+=fr[n+1];
ll sup=0,sdow=0,yuy=0,sumdow=0,mi=1e18;
for(int i=n;i>m;i--)
sumdow+=a[1][m];
sdow+=a[1][m];
sup+=a[0][m];
ll dl=0;
for(int i=m;i<=n;i++)
a[bl][m]-=fl[m-1];
a[br][n]-=fr[n+1];
return mi;
}void work()
dp[i][0]+=su*(sum-su);
dp[i][1]+=su*(sum-su);
} printf("%lld\n",dp[n][0]);
}int main()
2019.3.23 hdu 2544 最短路 解題報告
題目意思 給出 n 個路口和 m 條路,每一條路需要 c 分鐘走過。問從路口 1 到路口 n 需要的最短時間是多少。這題是最短路的入門題,從理解d i j k wg自創的,呵呵 到默打到修改,搞左兩日終於好了,哈哈哈 太感動了。第一次錯是 少了dijkstra 函式中的 for j 1 j n j ...
洛谷 P1144 最短路計數 解題報告
給出乙個 n 個頂點 m 條邊的無向無權圖,頂點編號為 1 n 問從頂點1開始,到其他每個點的最短路有幾條。第一行包含2個正整數 n,m 為圖的頂點數與邊數。接下來 m 行,每行2個正整數 x,y 表示有一條頂點 x 連向頂點 y 的邊,請注意可能有自環與重邊。共 n 行,每行乙個非負整數,第 i ...
洛谷最大子樹和解題報告
不知為什麼我做這道題莫名吃力,最後還是看了題解,大概是搜尋沒有學好的緣故吧。最近總是在學習一些其他的東西,現在看來還是打好基礎為妙。這道題其實不難,開三個陣列pre,next,last儲存邊與點的關係。不妨從1開始搜尋,找每條與它相鄰的邊,依次算出他們的最大子樹和,若大於零便累計起來。最後加上1節點...