HDU 4655 Cut Pieces
假设n个数构成的总数都分成了n段,总数是n*a1*a2*...*an。但是答案显然不会那么多。
对于相邻的两个ai,ai+1,如果选择相同的颜色,那么就减少了a1*a2*...*ai-1*min(ai,ai+1)*ai+2*ai+3*...*an。
不妨假设n=3,三个数分别是a,b,c。且a<b<c。
对于所有的排列,只有a,c,b是最优的,结果是3*a*b*c-a*b-b。
当n>3的时候同样可以得到结论:a1,an,a2,an-1...使得总的段数最多。
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 typedef long long LL; 5 #define MOD 1000000007 6 #define MAXN 1000010 7 using namespace std; 8 int arr[MAXN]; 9 int tmp[MAXN]; 10 LL ext_gcd(LL a, LL b, LL &x, LL &y) { 11 LL t, d; 12 if (b == 0) { 13 x = 1; 14 y = 0; 15 return a; 16 } 17 d = ext_gcd(b, a % b, x, y); 18 t = x; 19 x = y; 20 y = t - a / b * y; 21 return d; 22 } 23 LL invmod(LL a, LL n = MOD) { 24 LL x, y; 25 if (ext_gcd(a, n, x, y) != 1) 26 return -1; 27 return (x % n + n) % n; 28 } 29 int main() { 30 int T; 31 int n; 32 int i; 33 LL ans; 34 LL res; 35 LL mul; 36 int l, r; 37 scanf("%d", &T); 38 while (T--) { 39 scanf("%d", &n); 40 ans = n; 41 mul = 1; 42 for (i = 0; i < n; i++) { 43 scanf("%d", &arr[i]); 44 mul *= arr[i]; 45 mul %= MOD; 46 } 47 ans *= mul; 48 ans %= MOD; 49 sort(arr, arr + n); 50 for (l = 0, r = n - 1, i = 1; l <= r; l++, r--) { 51 if (l == r) { 52 tmp[i++] = arr[l]; 53 } else { 54 tmp[i++] = arr[l]; 55 tmp[i++] = arr[r]; 56 } 57 } 58 for (i = 2; i <= n; i++) { 59 res = mul * invmod(tmp[i] * (LL) tmp[i - 1]); 60 res %= MOD; 61 res *= min(tmp[i], tmp[i - 1]); 62 ans -= res % MOD; 63 ans = (ans % MOD + MOD) % MOD; 64 } 65 cout << ans << endl; 66 } 67 return 0; 68 }