Bobo has recently learned how to play Dota2. In Dota2 competitions, the mechanism of banning/picking heroes is introduced, modified and simplified as follows for the sake of the problem:
Suppose a game is played between two teams: Team A and Team B. Each team has a hero pool of nn heroes with positive utility scores a_1,\dots,a_na1,…,an and b_1,\dots,b_nb1,…,bn, respectively. Here we assume all heroes in two teams' hero pool are distinct.
The two teams then perform ban/pick operations alternately, with Team A going first. In one team's turn, it can either pick a hero for itself, or ban an unselected hero from the opponent's hero pool.
After 2n2n turns, all heroes are either picked or banned. Each team then needs to choose at most kk heroes from all heroes it picked to form a warband and the score for the warband is calculated as the sum of utility scores over all heroes in it.
Let s_A, s_BsA,sB be the score of the warband formed by Team A and Team B, respectively. Team A wants to maximize the value of s_A-s_BsA−sB while Team B wants to minimize it.
Bobo wants to know, what should be the final value of s_A-s_BsA−sB, if both teams act optimally? He's not really good at calculating this, so he turned to you for help.
An example of banning/picking heroes in Dota2. Source: TI10 True Sight
Input
The first line contains two integers n,k(1\leq n\leq 10^5,1\leq k \leq 10)n,k(1≤n≤105,1≤k≤10).
The second line contains nn integers a_1,a_2,\dots,a_na1,a2,…,an (1\leq a_i\leq 10^8)(1≤ai≤108), denoting the utility score of heroes for Team A.
The third line contains nn integers b_1,b_2,\dots,b_nb1,b2,…,bn (1\leq b_i\leq 10^8)(1≤bi≤108), denoting the utility score of heroes for Team B.
Output
Output an integer in one line, denoting the answer.
Sample 1
Inputcopy | Outputcopy |
---|---|
2 1 3 6 2 4 | 2 |
Sample 2
Inputcopy | Outputcopy |
---|---|
4 1 1 3 5 7 2 4 6 8 | 0 |
Sample 3
Inputcopy | Outputcopy |
---|---|
4 2 4 6 7 9 2 5 8 10 | 3 |
- #include<iostream>
- #include<algorithm>
- #include<map>
- #include<cstring>
- #include<vector>
-
- using namespace std;
- typedef long long ll;
- const ll INF = 0x3f3f3f3f3f3f3f;
- const int N = 1e5 + 10;
- const int K = 11;
-
- int n, k;
- int a[N], b[N];
- ll dp[2 * N][K][K];//双方操作总和,a选的英雄,b选的英雄
- //dp记录sa-sb
- int vis[2 * N][K][K];
-
- bool cmp(int a, int b)
- {
- return a > b;//从大到小排序
- }
-
- ll find(int s, int na, int nb)//s表示当前轮次进行了多少次操作,na表示A选择了几个英雄,nb表示B选择了几个英雄
- {
- //如果已经处理完所有的轮次,则返回0
- if (s > 2 * n) return 0;
-
- //如果之前已经计算过这个状态,则直接返回之前计算得到的结果
- if (vis[s][na][nb]) return dp[s][na][nb];
- vis[s][na][nb] = 1;
-
- //根据当前状态计算出A、B分别选择哪个英雄
- int ta = s / 2 - nb + na;
- int tb = (s + 1) / 2 - na + nb;
-
- //在奇数轮中,A先选择一个英雄,然后B再选择一个英雄
- if (s & 1)
- {
- int ta = ((s - 1) / 2 - nb) + na + 1;
- //在当前状态下,A不选择这个英雄
- dp[s][na][nb] = find(s + 1, na, nb);
- //如果A还没有选择k个英雄,并且ta小于等于n,则考虑选择这个英雄
- if (ta <= n && na < k) dp[s][na][nb] = max(dp[s][na][nb], find(s + 1, na + 1, nb) + a[ta]);
- return dp[s][na][nb];
- }
-
- //在偶数轮中,B先选择一个英雄,然后A再选择一个英雄
- else
- {
- int tb = (s / 2 - na) + nb + 1;
- //在当前状态下,B不选择这个英雄
- dp[s][na][nb] = find(s + 1, na, nb);
- //如果B还没有选择k个英雄,并且tb小于等于n,则考虑选择这个英雄
- if (tb <= n && nb < k) dp[s][na][nb] = min(dp[s][na][nb], find(s + 1, na, nb + 1) - b[tb]);
- return dp[s][na][nb];
- }
- }
-
- int main()
- {
- memset(dp, -1, sizeof dp);//初始化dp数组为-1
-
- scanf("%d %d", &n, &k);
-
- for (int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a + 1, a + n + 1, greater<int>());//从大到小排序
- for (int i = 1; i <= n; i++) scanf("%d", &b[i]); sort(b + 1, b + n + 1, greater<int>());
-
- //从状态(1,0,0)开始计算
- find(1, 0, 0);
-
- cout << dp[1][0][0] << endl;//输出最终的结果
-
- }