B - Checkout Assistant (CodeForces-19B)(01背包)

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

输入

第一行包含了数 n (1 ≤ n ≤ 2000)。接下来的 n 行,每行描述了一件商品,使用两个数 tici (0 ≤ ti ≤ 2000, 1 ≤ ci ≤ 109)。如果 ti 等于 0 ,那么 Bob 无法在收银员被商品 i 占用的时间窃取任何东西。

输出

输出一个数 — 问题的答案:Bob 必须支付的最少金额。

示例

输入

4
2 10
0 20
1 5
1 3

输出

8

输入

3
0 1
0 10
0 100

输出

111

题意:中文题,不过多叙述题意。

思路:这道题的话,比赛的时候没有看,然后早上补了一下。题里说每当收银员在被一件商品占用时间之后,Bob可以每过一秒钟顺走一件商品。所以我们转化一下,在第i件物品的时候,我们花费了Ci的价格买走了Ti+1件商品。所以我们把Ti+1看成第i件物品的体积,然后价值是Ci,这样的话就转化成01背包的问题了,问题就可以变成n件物品,从中选出若干件使得其体积不小于n且总价值最小的问题,然后用01背包就可以求解了。

AC代码:

#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#include <stack>
#include <vector>
typedef long long ll;
const int maxx=1000010;
const int inf=0x3f3f3f3f;
const int mod=10007;
using namespace std;
ll c[maxx],t[maxx];
ll dp[maxx];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld%lld",&t[i],&c[i]);
        t[i]++;
    }
    memset(dp,inf,sizeof(dp));
    dp[0]=0;
    for(int i=1; i<=n; i++)
    {
        for(int j=n; j>=t[i]; j--)
            dp[j]=min(dp[j],dp[j-t[i]]+c[i]);
        for(int j=t[i]-1; j>=0; j--)
            dp[j]=min(dp[j],c[i]);
    }
    printf("%lld\n",dp[n]);
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值