Checkout Assistant

解决Bob在收银员忙碌期间偷窃商品的问题,通过动态规划求解在给定时间内支付的最少金额,涉及0-1背包算法。
摘要由CSDN通过智能技术生成

题目描述

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.

输入格式

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 one number — answer to the problem: what is the minimum amount of money that Bob will have to pay.

题意翻译

题目描述

Bob 来到一家现购自运商店,将 n 件商品放入了他的手推车,然后到收银台付款。每件商品由它的价格 ci​ 和收银员扫描它的时间 ti​ 秒定义。

当收银员正在扫描某件商品时,Bob 可以从他的手推车中偷走某些其它商品。Bob 需要恰好 11 秒来偷走一件商品。Bob 需要付给收银员的最少钱数是多少?请记住,收银员扫描商品的顺序由 Bob 决定。

输入格式

输入第一行包含数 n(1≤n≤2000)。接下来 n 行每行每件商品由一对数 ti​,ci​(0≤ti​≤2000,1≤ci​≤109)描述。如果 ti​ 是 0,那么当收银员扫描商品 i 时,Bob 不能偷任何东西。

输出格式

输出一个数字—— Bob 需要支付的最小金额是多少。

输入输出样例

输入 #1复制

4
2 10
0 20
1 5
1 3

输出 #1复制

8

输入 #2复制

3
0 1
0 10
0 100

输出 #2复制

111

解析:
这道题的变形为 0-1背包的变形态;

在t时间内可以尽可能的使得价值最小。

dp[ i ] 表示在第i秒时间内,取完完成所有东西,价值最小。

初始化 dp[0] = 0;

状态转移方程:dp[j] = min(dp[j] , dp[j - t[i]] + c[i] );

其时间 的最大值应该为 max(time) = v + n ,v代表物品扫描的最多花费的那个时间,n为共有多少件物品。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
typedef long long ll;
const int M=2005,N=4005;
int n,t[M],v;
ll c[M],dp[N],ans=2e12;//注意ans的初始值 
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%lld",&t[i],&c[i]);
        t[i]++;//将t数组转换为用来存物品"体积" 
        v=max(v,t[i]);
    }
    v+=n;//算出最大体积 
    memset(dp,0x7f,sizeof(dp));
    dp[0]=0;//对dp数组进行初始化 
    for(int i=1;i<=n;i++)//在遍历到第i个物品时,使得最小的价值
        for(int j=v;j>=t[i];j--)
            dp[j]=min(dp[j],dp[j-t[i]]+c[i]);//01背包 
    for(int i=n;i<=v;i++) // 这个是检测的时间 
        ans=min(ans,dp[i]);//在所有满足条件的物品个数中寻找耗费最少的方案 
    printf("%lld",ans);
    return 0;
}

时间复杂度为O(v* n); v为扫描时间最长的物品加上n , n 为 物品的个数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值