【CodeForces - 19B】Checkout Assistant

Checkout Assistant

Bob came to a cash & carry store, put n items into his trolley, and went to the checkout counter to pay. Each item is described by its price ci and time ti in seconds that a checkout assistant spends on this item. While the checkout assistant is occupied with some item, Bob can steal some other items from his trolley. To steal one item Bob needs exactly 1 second. What is the minimum amount of money that Bob will have to pay to the checkout assistant? Remember, please, that it is Bob, who determines the order of items for the checkout assistant.

Input

The first input line contains number n (1 ≤ n ≤ 2000). In each of the following n lines each item is described by a pair of numbers ti, ci (0 ≤ ti ≤ 2000, 1 ≤ ci ≤ 109). If ti is 0, Bob won’t be able to steal anything, while the checkout assistant is occupied with item i.

Output

Output one number — answer to the problem: what is the minimum amount of money that Bob will have to pay.

Examples

Input

4
2 10
0 20
1 5
1 3

Output

8

Input

3
0 1
0 10
0 100

Output

111

中文题意:

Bob 来到一个现金便利店,放置了 n 件商品到他的手推车,然后前往收银台付款。每件商品用两个属性描述:价格 ci,时间 ti (收银员花在这件商品上的时间,以秒计)。当收银员被某件商品占用时间之时,Bob 可以从手推车窃取一些其他商品。Bob 恰好需要 1 秒钟,才能窃取一件商品。请问,Bob 必须最少支付多少钱给收银员?注意:商品递给收银员的顺序,由 Bob 决定。

思维引领:

首先看到这道题,我们可以很快速的知道,它一定是一个01背包的变种。为什么呢?那首先,我们来将题目条件都理清楚:
①只有n件物品(不是n种,排除完全背包和多重背包)
②价格与时间(联系到价值与重量,所谓重量也就是有限制,排除最长上升子序列)
那么,剩下的就是一个区间DP和路径等问题了,显然,这道题并不是针对序列的,或者是跟序列根本无关。5
那最后,就只剩下了01背包。
那我们该如何来定义状态呢?一般的想法就是以前i种物品或者是前i秒,但我们定义状态一定要根据影响状态来判断。而这题明显的影响状态有两个:①物品的价值②物品的时间,物品的价值我们都很熟悉了,那物品的时间呢?是重量?其实,像这样联想模型也不失为一个好方法。但是,去除模型,看看物品的时间到底和什么有关?(可以回头看看题目)
‘当收银员被某件商品占用时间之时,Bob 可以从手推车窃取一些其他商品’,对,物品数量,那么其实,若我们买了该物品,能够得到的物品数量为t[i]+1(加上买的物品),如此,便可以想到状态定义:d[j]为买j个物品所用金额的最小值,答案在d[n]。但需注意的是,这里是刚好j个,所以初始化……
应将除d[0]外的,都定为INF。
讲讲自己的失败经历:(可以无视
在做此题时,千万不要去想如今这个物品和前一个物品有什么关系,应将怎么排列,你见过DP01背包还要排序的吗?(优化除外),所以还是应将思维朝正确的方向指引

AC代码:

#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 2000
#define INF 0x3f
int N;
long long dp[MAXN+5];
long long t[MAXN+5],c[MAXN+5];
long long  read()
{
    long long x=0,f=1;
    char c=getchar();
    while('0'>c||'9'<c){if(c=='-')f=-1; c=getchar();}
    while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
long long minl(long long x,long long y)
{
    return x<y?x:y;
}
int main()
{
    N=read();
    for(int i=1;i<=N;i++)
    {
        t[i]=read(),c[i]=read();
        t[i]++;
    }
    memset(dp,INF,sizeof dp);
    dp[0]=0;
    for(int i=1;i<=N;i++)
    {
        int j;
        for(j=N;j>=t[i];j--)
            dp[j]=minl(dp[j],dp[j-t[i]]+c[i]);
        for(;j>=0;j--)
            dp[j]=minl(dp[j],c[i]);
    }
    printf("%lld\n",dp[N]);
 } 

thanks for your reading!

若喜欢的话,那便赏赐一个赞吧,谢谢>.<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值