省隊成員(大部分)都沒來...像我這種沙茶天天寫寫玄學演算法都能排在榜上面...果然正解寫掛的人遠比暴力拍對的人少啊...陸陸續續會補一些題解。(不過有些題太神了可能補不上題解
有n個物品,兩個袋子a和b。若物品i與j放在同乙個袋子裡,那麼代價為t[i][j],保證t[i][i]=0,t[i][j]=t[j][i]。
乙個袋子的代價d=袋子中兩兩物品代價的最大值。你需要將物品分配到兩個袋子中,最小化d(a)+d(b)。
2<=n<=250,0<=t[i][j]<=10^9。
陳旭大爺有一種暴力倍增的做法可以跑過去...跪爛
我們不妨設d(a)<=d(b),那麼我們列舉d(b),顯然可以二分d(a)判可行性。
對於兩物品i,j,如果d(a)d(b),那麼i和j就不能放在一起。
所以這就成了乙個2-sat問題,可以用經典的tarjan做法解決。
這樣是o(n^4logn)的,由於過於玄學只能得到部分分。
這個做法看起來已經十分優秀了,要怎麼優化呢?
我們發現列舉d(b)看起來就不太靠譜,真的要列舉o(n^2)種取值嗎?
顯然不要,我們考慮搞出一棵最大生成樹,以t為邊權。接下來考慮對這棵生成樹黑白染色,如果乙個集合b包括了兩種顏色的點,那麼顯然d(b)就是最大生成樹上的邊(可以由kruskal演算法的正確性得到)。否則b只包括一種顏色的點,只包含所有白點或只包含所有黑點(為什麼是所有點呢?因為如果是部分點,那麼a肯定包括另一種顏色的全部點。由於是最大生成樹,那麼d(a)>d(b))。所以我們只要嘗試這些d(b)即可。
這樣似乎就是o(n^3logn)的。
我們可以加一些奇技淫巧來優化,我的做法是將權值離散二分,然後每次根據最優解隨便剪剪枝,這樣就可以過了。
#include #include#include
#include
#include
using
namespace
std;
#define sz 666
int n,t[sz][sz],ls[sz*sz],ln=0,en=0
;int
ff[sz];
int gf(int
x)int m=0,fst[sz*sz*5],vb[sz*sz*5],nxt[sz*sz*5
];void ad_de(int a,int b)
void adde(int a,int
b) struct edg es[sz*sz];
bool
operator
< (edg a,edg b)
int ds[sz*sz],dn=0
;int
col[sz];
void dfs(int x,int
c)//
tarjan
namespace
tjvoid adde(int a,int
b) int ss[sz],sn=0,low[sz],dfn[sz],cnt=0,bl[sz],scc=0
;bool
ins[sz];
void
init()
void tarjan(int
x)
else
if(ins[b]) low[x]=min(low[x],dfn[b]);
}if(dfn[x]!=low[x]) return
;
int p; ++scc;
dowhile(p!=x);}}
bool ok(int da,int
db)
else
if(t>da)}}
for(int i=2;i<=2*n+1;i++)
for(int i=1;i<=n;i++) if(tj::bl[i*2]==tj::bl[i*2+1]) return0;
return1;
}struct f}__("
florida");
intmain()
for(int i=1;i<=n;i++)
sort(ls+1,ls+1+ln); ln=unique(ls+1,ls+1+ln)-ls-1
;
for(int i=1;i<=n;i++)
sort(es+1,es+1+en);
for(int i=1;i<=n;i++)
for(int i=1;i<=en;i++)
dfs(
1,0);
int maxn[2]=;
for(int i=1;i<=n;i++)
}ds[++dn]=maxn[0]; ds[++dn]=maxn[1
]; sort(ds+1,ds+1+dn); dn=unique(ds+1,ds+1+dn)-ds-1
;
int ans=2000000033
;
for(int i=0;i<=dn;i++)
ans=min(ans,ls[db]+ls[l]);
}printf(
"%d\n
",ans);
main();
}
7 5省隊集訓 tree
思路 樹形dp。先求最大值。令s x 為x的子樹中葉子節點的數量。f x 為到x時 為先手走,先手能取到的值在子樹中排第f x 小。g x 為到x時 為後手走,後手能取到的值在子樹中排第f x 小。對f x 先手應該往哪個子樹走呢?對於x的一棵子樹y,如果進入,那麼最終答案就是這棵子樹中第g y 小...
7 10省隊集訓夢工廠
思路 題面真心長.單調棧維護上凸殼即可 設sum i 為前i道工序的複雜度之和,g i 為第i個快樂最早開始生產的時間。因為我們要保證沒有兩個快樂同時出現在同一道工序,所以 g i g i 1 max sum j f i 1 sum j 1 f i 然後就是像斜率優化的過程了 sum j f i 1...
省隊集訓DAY2
假設我們列舉數列中長度為len的區間,那麼如何判斷兩個數列可以匹配呢?對於提取的數列從小到大排序,從大到小排序,然後兩兩配對,如果所有的都滿足 h 那麼就可以匹配。應該算是貪心吧。這樣做的時間複雜度是o n le n loglen 還是上面的思想,我們如何快速判斷呢?假設我們確定了提取出的區間數列,...