• 算法提高 种树


    Description

     

      种树

    Input

     

    输入描述:

      A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树。园林部门 得到指令后,初步规划出n个种树的位置,顺时针编号1到n。并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度。但由于A城市土壤 肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置。值得注意的是1号和n号也算相邻位置!)。

      最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大。如果无法将m棵树苗全部种上,给出无解信息。

    输入样例:

    7 3

    1 2 3 4 5 6 7

    Output

     

    输出描述:

      输入的第一行包含两个正整数n、m。

      第二行n个整数Ai。

    输出样例:

    15

    Sample Input 1 

    参考上文 

    Sample Output 1

    参考上文

    Hint

    HINT:时间限制:1.0s 内存限制:256.0MB

      输出一个整数,表示最佳植树方案可以得到的美观度。如果无解输出“Error!”,不包含引号。

    Source

    蓝桥杯练习系统 ID: 282 原题链接: http://lx.lanqiao.cn/problem.page?gpid=T282

    坑点:没有给出具体的数据范围

     

    思路:

    将所有情况分成两种,一是一定包含第一个位置,二是不包含第一个位置

    f[i][j] 表示的是从前1~i个位置中选出j个位置的最大值

    初始化(非常重要):求最大值的初始化为负无穷,求最小值的初始化为正无穷,所以这里将所有不合法的状态初始化为负无穷

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    
    using namespace std ;
    
    const int N = 110,INF = 0x3f3f3f3f ;
    
    
    int f1[N][N],f2[N][N] ;
    int a[N] ;
    int n, m ;
    
    int main(){
        cin >> n >> m ;
        
        for(int i=1;i<=n;i++){
            cin >> a[i] ;
        }
        
        if(n<m*2 && m != 1 && n != 1){
            cout << "Error!" << endl ;
        }else{
              //分成两种情况,所有的方案中包含1和不包含1
            for(int i=1;i<=m-1;i++){//f1[][]表示的是一定包含1
                f1[0][i] = f1[1][i] = -INF ;//用负无穷表示不可到达,所以f[0][i]必不可达(i>=1),f1[1][i]必不可达(i>=2)
            }
              f1[1][1] = 0 ;
            for(int i=1;i<=n-1;i++){
                for(int j=1;j<=m;j++){
                    if(i == 1){
                        f1[i][j] = max(f1[i][j],f1[i-1][j-1] + a[i]) ;
                    }else{
                        f1[i][j] = max(f1[i-1][j],f1[i-2][j-1] + a[i]) ;
                    }
                }
            }
            
            for(int i=1;i<=m;i++){
                f2[0][i] = -INF ;
                f2[1][i] = -INF ;//第一个物品必不选
            }
            for(int i=2;i<=n;i++){
                for(int j=1;j<=m;j++){
                    f2[i][j] = max(f2[i-1][j],f2[i-2][j-1]+a[i]) ;
                }
            }
            
            cout << max(f2[n][m],f1[n-1][m]) << endl ;
        }
        
        
        
        return 0 ;
    }

    ...

     

  • 相关阅读:
    Intellij IDEA + Jrebel
    WebConfig配置详解大全
    .Net 获取前端传递的数据
    js 格式验证大全
    EasyUI DataGrid 时间格式化、字符串长度截取
    SQL取某个字符串最后一次出现的位置后面的字符串方法
    公民身份号码校验码算法(C#版)
    组织机构代码校验码生成算法(C#版)
    MySQL实现根据当前ID读取上一条和下一条记录
    js jquery.pagination.js分页
  • 原文地址:https://www.cnblogs.com/gulangyuzzz/p/12343133.html
Copyright © 2020-2023  润新知