花园最大总美丽值

该文章描述了一个问题,园丁Model试图通过在n个花园种植花朵来最大化总美丽值。已知每个花园已有花朵数、可新增花朵数、目标完整花园所需的花朵数以及不完整花园的评分系数。文章提供了两个示例并给出了解决问题的算法思路,包括根据full和partial的相对大小决定优先级。最后,给出了C语言的代码实现来解决这个问题。

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

题目描述

Modeln 个花园的园丁,她想通过种花,最大化她所有花园的总美丽值。

给你一个下标从 0 开始大小为 n 的整数数组 flowers ,其中 flowers[i] 是第 i 个花园里已经种的花的数目。已经种了的花不能移走。同时给你 newFlowers ,表示 Model 额外可以种花的最大数目。同时给你的还有整数 targetfullpartial

如果一个花园有至少 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 ;
 } 

新手小白,请多指教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值