2013多校第六场

本文介绍了一道名为HDU4655的算法题目解决方案,该问题要求求解给定序列下所有可能的颜色涂法中产生的段数的最大值。通过分析,给出了一种计算相邻位置颜色相同的数量的方法,并提供了具体的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hdu 4655

题意:给一个序列,每个位置可以涂1~ai种颜色,连续不相同的颜色为一段,对于一个排列,所有的涂色方法产生的段数为S,求最大的S;

分析:对于一个排序,所有的段数为n*{a1*a2*...*an} - (相邻两个位置涂相同颜色的个数S);

怎么计算相邻两个位置涂相同颜色的个数S?

p[i]表示前缀积,即p[i] = a1*a2*..*ai; 

q[i]表示后缀积,即q[i] = ai*...*an;

S =sum( p[i-1]*q[i+2]*min(ai,ai+1) ) (0<=i<n);即如果相邻两个相等就减去一;

要使S最小,即min(ai,ai+1)尽量小,假设序列ai<ai+1,a1,an,a2,an-1...就是最优序列;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<cmath>
 7 using namespace std;
 8 typedef long long LL;
 9 const int Mod = (int)1e9+7;
10 const int N = 1000000+10;
11 int a[N],b[N];
12 int n;
13 LL p[N],q[N];
14 int main(){
15     int T; scanf("%d",&T);
16     while (T--) {
17         scanf("%d",&n);
18         for (int i = 0; i < n; i++) {
19             scanf("%d",&a[i]);
20         }
21         sort(a,a+n);
22         int l = 0, r = n - 1;
23         for (int i = 0; i < n; i++) {
24             if (i%2 == 0) {
25                 b[i] = a[l++];
26             }else b[i] = a[r--];
27          //   cout<<b[i]<<" ";
28         }//cout<<endl;
29         LL sum = n;
30         p[0] = b[0]; q[n] = 1;
31         for (int i = 1; i < n; i++) p[i] = p[i-1] * b[i] % Mod;
32         for (int i = n-1; i >= 0; i--) q[i] = q[i+1] * b[i] % Mod;
33         for (int i = 0; i < n; i++) sum = sum * b[i] % Mod;
34         sum = (sum - (LL)min(b[0],b[1])*q[2]%Mod + Mod ) % Mod;
35         for (int i = 1; i < n-1; i++) {
36             sum = (sum - p[i-1]*q[i+2] % Mod * min(b[i],b[i+1]) % Mod + Mod ) % Mod;
37         }
38         cout<<sum<<endl;
39     }
40 
41     return 0;
42 }
View Code

 

转载于:https://www.cnblogs.com/Rlemon/p/3247644.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值