1. 小区划分
动规。题目略坑,通过样例发现,每个住户必须属于一个小区。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 5 using namespace std; 6 7 double f[810][85], A[810], B[810]; 8 9 int main() 10 { 11 int i, j, k, N, K; 12 scanf("%d%d", &N, &K); 13 for (i = 1; i <= N; ++i) 14 scanf("%lf", &A[i]), A[i] += A[i-1]; 15 for (i = 1; i <= N; ++i) 16 scanf("%lf", &B[i]), B[i] += B[i-1]; 17 for (i = 1; i <= N; ++i) 18 for (k = 1; k <= i && k <= K; ++k) { 19 if (k == 1) { f[i][1] = fabs(A[i]-B[i]); continue; } 20 for (j = k-1; j < i; ++j) { 21 f[i][k] = max(f[i][k], f[j][k-1]+fabs((A[i]-A[j])-(B[i]-B[j]))); 22 } 23 } 24 printf("%.6lf ", f[N][K]); 25 return 0; 26 }
2. 直线的交点
把各直线与两条平行线的交点处理一下就转换成了逆序对问题。看代码比较容易理解。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int _N = 120000; 7 8 typedef long long LL; 9 10 double K[_N], B[_N], X[_N], Y[_N], SX[_N], SY[_N], C[_N], GG[_N], k, a, b; 11 int N; 12 13 void Add(int k, int d) 14 { 15 for (int i = k; i <= N; i += i & -i) 16 C[i] += d; 17 return; 18 } 19 20 LL GetSum(int k) 21 { 22 LL tmp = 0; 23 for (int i = k; i; i ^= i & -i) 24 tmp += C[i]; 25 return tmp; 26 } 27 28 int main() 29 { 30 int i; 31 scanf("%lf%lf%lf%d", &k, &a, &b, &N); 32 33 for (i = 1; i <= N; ++i) { 34 scanf("%lf%lf", &K[i], &B[i]); 35 X[i] = (B[i]-a)/(k-K[i]); 36 SX[i] = X[i]; 37 Y[i] = (B[i]-b)/(k-K[i]); 38 SY[i] = Y[i]; 39 } 40 41 sort(SX+1, SX+1+N); 42 sort(SY+1, SY+1+N); 43 44 for (i = 1; i <= N; ++i) { 45 LL tmpx = (LL)(lower_bound(SX+1, SX+1+N, X[i])-SX); 46 LL tmpy = (LL)(lower_bound(SY+1, SY+1+N, Y[i])-SY); 47 GG[tmpx] = tmpy; 48 } 49 50 51 LL ggans = 0; 52 for (i = 1; i <= N; ++i) { 53 ggans += GetSum(N)-GetSum(GG[i]); 54 Add(GG[i], 1); 55 } 56 printf("%lld ", ggans); 57 58 return 0; 59 }
3. 数三角形
各种计数推,只要能搞出来就好了。
1 #include <cstdio> 2 3 typedef long long LL; 4 5 LL cnt[120000][2]; 6 7 LL C_k_2(LL v) { return v >= 2 ? v*(v-1)/2 : 0; } 8 9 int main() 10 { 11 LL N, M, i; 12 scanf("%lld%lld", &N, &M); 13 for (i = 1; i <= M; ++i) { 14 LL x, y, w; 15 scanf("%lld%lld%lld", &x, &y, &w); 16 ++cnt[x][w-1], ++cnt[y][w-1]; 17 } 18 LL X = 0, Y = 0; 19 for (i = 1; i <= N; ++i) { 20 LL cnt1 = cnt[i][0], cnt2 = cnt[i][1]; 21 LL cnt3 = N-1-cnt[i][0]-cnt[i][1]; 22 X += cnt1*cnt2+cnt2*cnt3+cnt1*cnt3; 23 Y += C_k_2(cnt1)+C_k_2(cnt2)+C_k_2(cnt3); 24 } 25 printf("%lld ", X-2*Y); 26 27 return 0; 28 }