hdu 1300 Pearls(线性dp/斜率优化)

题意:给你n个物品的数量和价格,单个购买物品时数量加10(买一个花11个钱),连续购买多个时,数量总和加10,以结束物品单价为准(价格是单价递增的,是以最贵的计算,所以就是最后一个物品),求最小单价

思路:就是简单的n2dp,注意初始化为0x3f,而不是0,还有就是在选取第j个物品时要从0开始,这样可以少写一个从0转移单个的直接赋值的语句,斜率优化下次再更新

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=105;

int a[maxn],val[maxn],dp[maxn],pre[maxn];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        memset(dp,0x3f,sizeof(dp));
        scanf("%d",&n);
        pre[0]=0;
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&val[i]),pre[i]=pre[i-1]+a[i];
        dp[0]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<i;j++){
                dp[i]=min(dp[i],dp[j]+(pre[i]-pre[j]+10)*val[i]);
            }
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}

 斜率优化:有点问题,下面队列维护的为下凸壳,为什么需要l+1<R

代码:

-----------------二更----------------

模仿bzoj 1010 hzw的单调队列写法,(ps:hzw写法中l首先赋值为1,r为0,que[++r]=0,这里r先进行++,在进行赋值,这样在写单调队列的时候就直接用que[r]作为队列末尾就行了,方便易思考)

下面讨论为什么维护下凸壳的原因,等待三更

 

#include <bits/stdc++.h>
using namespace std;
const int maxn=105;

int a[maxn],val[maxn],dp[maxn],pre[maxn];
int que[maxn],l,r;

double slop(int j,int k)
{
    return (dp[j]-dp[k])*1.0/(pre[j]-pre[k]);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        memset(dp,0x3f,sizeof(dp));
        l=1,r=0;
        scanf("%d",&n);
        pre[0]=0;
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&val[i]),pre[i]=pre[i-1]+a[i];
        dp[0]=0;
        que[++r]=0;
        for(int i=1;i<=n;i++){
            while(l<r&&slop(que[l],que[l+1])<=val[i])l++;
            int j=que[l];
            dp[i]=dp[j]+(pre[i]-pre[j]+10)*val[i];
            while(l<r&&slop(que[r],que[r-1])>slop(que[r],i)) r--;
            que[++r]=i;
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/lalalatianlalu/p/8527546.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值