百度之星初赛A第一题
第一题:图标排列
百度应用平台上有很多有趣的应用,每个应用都由一个开发者开发,每个开发者可能开发一个或多个应用。百度的工程师们想把应用尽可能好的推荐给用户。
研究发现,同一个开发者开发的程序的图标有很大的相似性。如果把同一个开发者开发的应用放在一起,用户很快就会厌倦相似的图标,如果把这些图标穿插摆放效果就会好很多。
现在工程师想给用户推荐来自m个开发者的n个应用,在推荐的时候这些应用的图标将排成整齐的一行展示给用户,相邻两个图标之间的距离正好是1,工程师们想让这些图标尽可能的穿插摆放。为了衡量穿插摆放的效果,给每个图标定义一个“分离度”,分离度的值是指当前图标和它左边最近的来自同一个开发者的图标之间的距离。如果一个图标左边没有来自同一个开发者的图标,则分离度为0。所有图标穿插摆放效果的值定义为所有图标的分离度之和。
已知每个开发者开发的应用个数,请帮助百度的工程师找到图标穿插摆放效果的最大值。
输入描述
输入的第一行包含两个整数n和m,用一个空格分隔,分别表示应用的个数和开发者的个数。
第二行包含m个正整数,相邻两个数之间用一个空格分隔,表示每个开发者开发的应用个数,这些整数之和必然等于n。
输出描述
输出一个整数,表示图标穿插摆放效果的最大值。
样例输入
8 3
3 3 2
样例输出
15
提示
对于20%的数据,n≤ 10;
对于40%的数据,n≤ 100。
对于100%的数据,1≤ m ≤ n ≤ 100,000
这道题目一看就是数学题,我讲一下我的思路:
首先我们将所有图标都看成小球,不同开发者代表不同的颜色;
(1)当某一种颜色的小球只有一个时,它不会产生分离度,所以可以忽略。
(2)当某一种颜色的小球个数大于等于两个时,它会产生分离度,我们期望达到最大的分离度,
为了具体说明,我们将颜色用A,B,C。。。。来表示,位置用1,2,3.。。。来表示
A ........A.......A......A(假设这是最后一个A)........ L1
1 5 6 9
A ........A.......A......A(假设这是最后一个A)........ L2
1 2 3 9
由此得出所有A的分离度之和 L1=L2=8=9-1
那么也就是说所有同色球的分离度之和有开头和结尾的球的位置决定,与中间球的摆放方式无关 (自己证明一下即可)
所以我们每一次都将同色球个数不小于2的置于序列的开头和结尾,以达到每一个同色球产生最大的分离度
每放一个同色球,序列长度就要减去2表示开头和结尾以放球
1 #include <stdio.h>
2 int main()
3 {
4 int n,m;
5 scanf("%d %d",&n,&m);
6 int tmp,sum=0;
7 while(m--)
8 {
9 scanf("%d",&tmp);
10 if(tmp>1)
11 {
12 n-=2; //表示两个位置被占
13 sum+=(n+1); //产生的最大分离度
14 }
15 }
16 printf("%d\n",sum);
17 return 0;
18 }
但是在仔细一点,不满足于这种形式由以上算法可以退出公式 sum=(n-c)*c;(c不小于2的同色球个数)
1 #include <stdio.h>
2 int main()
3 {
4 int n,m;
5 scanf("%d %d",&n,&m);
6 int tmp,sum=0,c=0;
7 while(m--)
8 {
9 scanf("%d",&tmp);
10 if(tmp>1) c++;
11 }
12 sum=(n-c)*c;
13 printf("%d\n",sum);
14 return 0;
15 }