Assignments
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1769 Accepted Submission(s): 837
2 5 4 2 3 5
4
题意:有两个长度为N(N<=1000)的序列A和B,把两个序列中的共2N个数分为N组,使得每组中的两个数分别来自A和B,每组的分数等于max(0,组内两数之和-t),问所有组的分数之和的最小值。
解法:贪心。将A B排序,A中最大的和B中最小的一组,A中第二大的和B中第二小的一组,以此类推。给出一个简单的证明:若有两组(a0,b0), (a1,b1)满足a0>=a1&&b0>=b1,这两组的得分为max(a0+b0-t,0)+max(a1+b1-t,0) >= max(a0+b1-t,0)+max(a1+b0-t,0)即(a0,b1),(a1,b0)的得分,所以交换b0 b1之后可以使解更优。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<set>
#include<vector>
#define F first
#define S second
#define PI acos(-1.0)
#define E exp(1.0)
#define INF 0xFFFFFFF
#define MAX -INF
#define len(a) (__int64)strlen(a)
#define mem0(a) (memset(a,0,sizeof(a)))
#define mem1(a) (memset(a,-1,sizeof(a)))
using namespace std;
__int64 gcd(__int64 a, __int64 b) {
return b ? gcd(b, a % b) : a;
}
__int64 lcm(__int64 a, __int64 b) {
return a / gcd(a, b) * b;
}
__int64 max(__int64 a, __int64 b) {
return a > b ? a : b;
}
__int64 min(__int64 a, __int64 b) {
return a < b ? a : b;
}
int main() {
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n, t, sum, a[1010], b[1010];
while (scanf("%d%d", &n, &t) != EOF) {
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < n; i++) {
scanf("%d", &b[i]);
}
sort(a, a + n);
sort(b, b + n);
sum = 0;
for (int i = 0; i < n; i++) {
sum += max(0, a[i] + b[n - 1 - i] - t);
}
printf("%d\n", sum);
}
return 0;
}