题目描述
Model 是 n 个花园的园丁,她想通过种花,最大化她所有花园的总美丽值。
给你一个下标从 0 开始大小为 n 的整数数组 flowers ,其中 flowers[i] 是第 i 个花园里已经种的花的数目。已经种了的花不能移走。同时给你 newFlowers ,表示 Model 额外可以种花的最大数目。同时给你的还有整数 target ,full 和 partial。
如果一个花园有至少 target 朵花,那么这个花园称为完善的,花园的总美丽值为以下分数之和 :
完善花园数目乘以 full.
剩余不完善花园里,花的最少数目乘以 partial。如果没有不完善花园,那么这一部分的值为 0。
请你返回 Model 种最多 newFlowers 朵花以后,能得到的最大总美丽值。
输入输出格式
输入格式
第一行有 n 个整数,表示花园里已经种花的数目,每个整数用一个空格隔开;
第二行有一个整数,表示额外可以种花的最大数目。
第三行有一个整数,表示完善的花园至少需要的花朵数。
第四行有一个整数。
第五行有一个整数。
输出格式
一行输出整数,表示能得到的最大总美丽值。
输入输出样例1
输入
1 3 1 1
7
6
12
1
输出14
解释(可选)
Model 可以按以下方案种花
在第 0 个花园种 2 朵花
在第 1 个花园种 3 朵花
在第 2 个花园种 1 朵花
在第 3 个花园种 1 朵花 花园里花的数目为 [3,6,2,2] 。总共种了 2 + 3 + 1 + 1 = 7 朵花。 只有 1 个花园是完善的。 不完善花园里花的最少数目是 2 。 所以总美丽值为 1 * 12 + 2 * 1 = 12 + 2 = 14 。 没有其他方案可以让花园总美丽值超过 14 。
输入输出样例2
输入
2 4 5 3
10
5
2
6
输出
30
解释(可选)
Model 可以按以下方案种花
在第 0 个花园种 3 朵花
在第 1 个花园种 0 朵花
在第 2 个花园种 0 朵花
在第 3 个花园种 2 朵花 花园里花的数目为 [5,4,5,5] 。总共种了 3 + 0 + 0 + 2 = 5 朵花。 有 3 个花园是完善的。 不完善花园里花的最少数目为 4 。 所以总美丽值为 3 * 2 + 4 * 6 = 6 + 24 = 30 。 没有其他方案可以让花园总美丽值超过 30 。
说明提示
可以让所有花园都变成完善的,但这样她的总美丽值反而更小。
算法设计
情况比较复杂,首先从full和partial的值判断,full较大时则需要先增加完善花园的数量,然后再去减少不完善花园的最小花数,以实现总美丽值最大化。
而当partial大于full时,就不需要增加完善花园的数量,直接减少不完善花园的最小花数即可,
补充花数理论可以超过target的,这种情况并没有写入代码。
代码实现
#include<stdio.h>
#define N 99
int min( int x , int y )
{
return (x<y?x:y) ;
}
int max( int x , int y )
{
return (x>y?x:y) ;
}
int main()
{
int n , target , full , partial ,newFlowers;
int flowers[N];
for( n = 0 ; ; n ++ )
{
char c ;
c = getchar() ;
if( c == '\n')break;
if( c == ' ')
{
n--;
continue;
}
flowers[n] = (int)c - '1' + 1 ;
}
/*
printf(" n = %d\n",n);
/*
int i ;
for( i = 0 ; i < n ; i++)
printf("flowers[%d] = %d\n",i,flowers[i]);
*/
scanf("%d%d%d%d",&newFlowers,&target,&full,&partial);
/*
printf(" newFlowers = %d\n",newFlowers);
printf(" target = %d\n",target);
printf(" full = %d\n",full);
printf(" partial = %d\n",partial);
*/
int i ,fullnum = 0 ,sumgap = 0 ,maxgap = 0 , mingap ;
mingap = target ;
//fullnum 为完善花园数目
int gap[N] = { 0 };
//gap 数组存放每个花园中花数与 target 的差值
for ( i = 0 ; i < n ; i ++ )
{
if( flowers[i] >= target)fullnum++;
//完善花园数目
if( flowers[i] < target )
gap[i] = target - flowers[i] ;
//非完善花园差值
sumgap += gap[i];
//非完善花园总差值
mingap = min(mingap,gap[i]);
maxgap = max(maxgap,gap[i]);
}
/*
printf("maxgap = %d , mingap = %d\n",maxgap,mingap);
*/
for ( i = 0 ; i < n-1 ; i ++ )
{
int j ;
for ( j = 0 ; j < n-i -1 ; j++)
{
int tmp ;
if( gap[j] > gap[j+1])
{
tmp = gap[j] ;
gap[j] = gap[j+1] ;
gap[j+1] = tmp ;
}
}
}//按升序排列 gap
/*
for ( i = 0 ; i < n ; i++ )
printf("gap[%d] = %d\n", i , gap[i]) ;
*/
if(full > partial)
{
if(newFlowers>= sumgap)
{
printf("%d",full*n) ;
return 0 ;
}
//此时非完善花园为 0
for( i = 0 ; newFlowers > gap [i] ; i++ )
{
newFlowers -= gap[i];
fullnum ++ ;
}
for( i = n -1 ; newFlowers>= 0 ; i -- )
{
if(gap[i] == maxgap)
{
gap[i] -- ;
newFlowers-- ;
}//newFlowers 不够时从花数最少的花园开始加
int j ;
for( j = 0 ; j < n ;j++)
maxgap = max(0,gap[j]);
//取当前 gap 数组中最大的值
}
}
else
{
if(newFlowers>= sumgap)
{
printf("%d",partial*target) ;
return 0 ;
}
else
{//因为此时 partial > full 所以不增加 fullnum 直接从花数最少的花园开始加
for( i = n -1 ; newFlowers>= 0 ; i -- )
{
if(gap[i] == maxgap)
{
gap[i] -- ;
newFlowers-- ;
}//newFlowers 不够时从花数最少的花园开始加
int j ;
for( j = 0 ; j < n ;j++)
maxgap = max(0,gap[j]);
//取当前 gap 数组中最大的值
}
}
}
/*
printf("maxgap = %d\n",maxgap);
*/
printf("%d",full*fullnum + (target - maxgap )*partial) ;
return 0 ;
}
新手小白,请多指教。