• 选数


    选数


    题目描述

    n个数排成一排,从中选出k个数,使得和最大。要求相邻的两个数中最多选一个

    输入输出格式

    输入

    共两行,第一行为n,k
    第二行共有n个数,即题意中的数列

    输出

    仅一个数字,表示最大的和。

    样例输入输出

    输入:

    5 2
    5 2 1 -1 6

    输出

    11

    数据范围

    40%满足 (n<=20,k<=3)

    60%满足 (n<=800,k<=10)

    100%满足 (n<=2000,k<=100)


    设dp数组为[i][j][k]

    表示前i个数选j个且第i个数选与不选(k=1为选,k=0为不选)的最优解

    dp[i][j][1]=dp[i-1][j-1][0]+a[i]

    若第i个数选的话,那么就是前i-1的数,第i-1个数不选,已经选了j-1的数的最优值加上本身的值。

    dp[i][j][0]=max(dp[i-1][j][1],dp[i-1][j][0])

    若第i个数不选,则从前i-1的数,第i-1个数选或不选,已经选了j-1的数两种状态下的最优值转移过来。(要注意当前最优有可能不是全局最优,所以要从两种状态中转移过来)


    #include<iostream> 
    using namespace std;
    int dp[2010][101][2];
    int a[2010];
    int main()
    {
    	cin.sync_with_stdio(false);
    	int n,k;
    	cin>>n>>k;
    	for(int i=1;i<=n;i++)
    		cin>>a[i];
    	dp[1][1][1]=a[1];
    	dp[1][0][0]=0;
    	for(int i=2;i<=n;i++)
    		for(int j=1;j<=k;j++)//从1开始,防止下标越界。而且选0个数的值全都是0,不用转移
    		{
    			dp[i][j][1]=dp[i-1][j-1][0]+a[i];
    			dp[i][j][0]=max(dp[i-1][j][1],dp[i-1][j][0]);
    		}
    	printf("%d",max(dp[n][k][1],dp[n][k][0]));
    }
    
  • 相关阅读:
    2020了,初/中级前端面试你应该知道的(上)
    Vue页面权限控制和动态添加路由
    Javascript获取数组中最大和最小值
    localStorage和cookie的跨域解决方案
    移动端常见问题汇总
    码云git本地仓库链接远程仓库
    IntelliJ IDEA Activation code亲测可用
    Sping4之注入参数
    Sping4之依赖注入
    Spring核心之IOC
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/8495933.html
Copyright © 2020-2023  润新知