题目链接:http://codeforces.com/problemset/problem/19/B
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
4
2 10
0 20
1 5
1 3
8
3
0 1
0 10
0 100
111
题目大意:买了N件物品需要结账,每件物品的价格为c,结账花费时间为t,在t的时间内,1秒可以偷一件物品,问你最少花多少钱拿走N件物品
思路:其实一眼就可以知道是01背包了,每个物品只有付钱与不付钱两种选择,01背包来求解的话,有背包体积和物品体积和价格,在这里不好处理的就是背包体积到底是多少
这一点比赛的时候一直困扰自己,导致最后也没做出来,一直在想体积怎么固定呢,blabla...
其实是自己想的太复杂了,这样去想 dp[N]表示拿走N件物品所需的最小花费。那么答案就是dp[N]
枚举每一个物品,付钱或者不付钱两种情况,付钱的话,可以贡献t[i]的时间,那么我们就可以多拿走t[i]个物品
这样枚举了每一件物品拿与不拿,最终就是答案了
看代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<stack> #include<map> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<stack> #include<map> #include<queue> #include<cmath> using namespace std; typedef long long LL; typedef unsigned long long ull; #define sc1(a) scanf("%lld",&a) #define pf1(a) printf("%lld ",a) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const LL INF=1e18; const ull base=2333; const int maxn=2e3+55; const int maxm=1e4+50; const int maxv=1e6+5; const int maxk=1e8+5; const int mod=1e9+7; LL dp[maxn]; struct Node { LL c,t; }a[maxn]; /** dp[i]表示i件物品所需的最小价值 所以答案就是dp[n] 对于每一个物品,都有付钱与不付钱两种情况 付钱的话,服务员需要花费t[i]的时间,也就相当于我们只要付这一个物品的钱 同时再送我们t[i]件物品 不付钱的话,不贡献物品 */ int main() { LL N;sc1(N); for(LL i=1;i<=N;i++) { sc1(a[i].t);sc1(a[i].c); dp[i]=INF; } for(LL i=1;i<=N;i++) //枚举每一个物品 { for(LL j=N;j>=1;j--) { if(j-1<=a[i].t) dp[j]=min(dp[j],a[i].c);//表示只要付这一件物品,剩下的j-1建物品全部可以偷走 else dp[j]=min(dp[j],dp[j-1-a[i].t]+a[i].c);//只要付这一件物品,可以拿走a[i].t+1件物品(包括本身) } } pf1(dp[N]); return 0; } /** */