【2019牛客暑期多校训练营(第二场)- F】Partition problem(dfs,均摊时间优化)
題干:
鏈接:https://ac.nowcoder.com/acm/contest/882/F
來(lái)源:牛客網(wǎng)
?
Given 2N people, you need to assign each of them into either red team or white team such that each team consists of exactly N people and the total competitive value is maximized.
?
Total competitive value is the summation of competitive value of each pair of people in different team.
?
The equivalent equation is?∑i=12N∑j=i+12N(vij?if?i-th?person?is?not?in?the?same?team?as?j-th?person?else?0)\sum_{i=1}^{2N} \sum_{j=i+1}^{2N} (v_{ij} \text{ if i-th person is not in the same team as j-th person else } 0 )∑i=12N?∑j=i+12N?(vij??if?i-th?person?is?not?in?the?same?team?as?j-th?person?else?0)
輸入描述:
The first line of input contains an integers N.Following 2N lines each contains 2N space-separated integers vijv_{ij}vij??is the j-th value of the i-th line which indicates the competitive value of person i and person j.* 1≤N≤141 \leq N \leq 141≤N≤14 * 0≤vij≤1090 \leq v_{ij} \leq 10^{9}0≤vij?≤109 * vij=vjiv_{ij} = v_{ji}vij?=vji?輸出描述:
Output one line containing an integer representing the maximum possible total competitive value.示例1
輸入
復(fù)制
1 0 3 3 0輸出
復(fù)制
3題目大意:
時(shí)限4秒。
將2*n個(gè)人分到兩個(gè)team,每個(gè)team必須恰好有n個(gè)人,如果i,j兩個(gè)人位于不同的team,那么收益增加 a[i][j],求分配的最大收益
第一行輸入n
第二行輸入一個(gè)(2*n)*(2*n)的矩陣。
求最大收益。
解題報(bào)告:
? 最暴力的方法是C(2*n,n)枚舉,但是最后對(duì)于每一種情況算答案的時(shí)候需要n^2處理,這樣總復(fù)雜度就是O( C(2*n,n) * n^2 ),在n=14的情況下是會(huì)T的。想辦法優(yōu)化掉一個(gè)N。(? C(28,14) = 40116600)
可以這么轉(zhuǎn)化一下問(wèn)題,其實(shí)可以看成本來(lái)2*n個(gè)人都在一個(gè)team中,現(xiàn)在要拽其中一些人去另一個(gè)team,所以每當(dāng)拽一個(gè)人去另一個(gè)team的時(shí)候,就減去對(duì)應(yīng)的貢獻(xiàn)。這樣的好處就是,把最后統(tǒng)計(jì)需要On^2的時(shí)間均攤到每一次的dfs中線性完成,這樣總復(fù)雜度就是O( C(2*n,n) * n?),可以接受。這題時(shí)限4秒。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define FF first #define SS second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; const ll mod = 1e9 + 7; ll ma; vector<int> v; int n; ll a[33][33],d[33];//d[i]代表i和其他所有點(diǎn)連邊的權(quán)值和。 void dfs(ll x,ll ans) {if(v.size()==n) {ma = max(ma,ans); return ;}if(v.size()>n || x>=2*n) return ;ll now=d[x];for(auto s:v) now -= a[x][s]*2;//選 v.push_back(x);dfs(x+1,ans+now);//不選 v.pop_back();dfs(x+1,ans); } int main() {scanf("%d",&n);for(int i=0; i<2*n; i++)for(int j=0; j<2*n; j++) {scanf("%lld",&a[i][j]);d[i]+=a[i][j];}dfs(0,0);cout << ma <<endl;return 0 ; }總結(jié)
以上是生活随笔為你收集整理的【2019牛客暑期多校训练营(第二场)- F】Partition problem(dfs,均摊时间优化)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 申请信用卡会给单位打电话吗 银行电话回访
- 下一篇: 【牛客 - 327G】处女座与复读机(可