leetcode 1014. 最佳观光组合 C语言 动态规划

题目

分析题目

将所求部分分为两部分 values[i]+values[j]+i-j = (values[i]+i)+(values[j]-j)

可以假定j是固定的,即(values[j]-j)是固定的,这里先不管j,题目中要求i<j,且要求和的最大值,就要求在区间[0,j)之间(values[i]+i)的最大便,求解问题就变成了在左闭右开前缀最大值的问题

运用动态规划

设计状态:求第i项前面的最大值(包含第i项)就转移到求【第i-1项之前的最大值(包含第i-1项)与第i项之间】的最大值

写出状态方程:Rmix[i]=max(Rmix[i-1],a[i]+i);

设定初始状态:Rmix[0]=a[0];        maxn=rmix[0]+values[1]+1;

执行状态转移

返回最终解 

代码段 

int max(int a,int b)                        //定义一个求最大值的函数
{
    return a>b?a:b;
}

void PreMax(int* a,int n,int*Premax)        //定义一个求前缀最大值的函数
{
    int i;
    for(i=0;i<n;i++)
    {
        if(i==0)
        {
            Premax[i]=a[i]+i;                //设置初始状态
        }
        else
        {
            Premax[i]=max(Premax[i-1],a[i]+i); //执行状态转移
        }
    }
}


#define MAXN 50005
int maxScoreSightseeingPair(int* values, int valuesSize){
    int premax[MAXN];                        //定义一个存放前缀最大值的数组
    int j;
    int maxn;                                //存放values[i]+i+values[j]-j最大值的变量
    PreMax(values,valuesSize,premax);

    for(j=1;j<valuesSize;j++)                //i<j,故j从第二项开始 下标为1
    {
        if(j==1)
        {
            maxn=premax[0]+values[1]-1;      //设定初始状态
        }
        else                             //移动j求出每个不同j对应的maxn并把最大值赋给maxn;
        {                               
            maxn=max(premax[j-1]+values[j]-j,maxn);
        }
    }
    return maxn;
}

执行结果

 

 

时间复杂度和空间复杂度分析

代码共执行2n-1次,因此时间复杂度为O(n)

分配了一个数组,因此空间复杂度为O(n)

总结

1 - 灵活处理问题,要假定右端是固定的,问题就变成了在左闭右开前缀最大值的问题

2 - 初始状态的设定,不要漏掉i,j

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值