RQNOJ 671 纯洁的买卖:无限背包

题目链接:https://www.rqnoj.cn/problem/671

题意:

  ALEJ要通过倒卖东西来赚钱。

  现在他有m元经费。

  有n种物品供他选择,每种物品数量无限。

  第i件物品的买入价为c[i],卖出价为r[i],每卖出一件物品i后,要交c[i]的税。

  问:一次买卖之后,经费最多有多少。

 

题解:

  注:(1)“买”和“卖”是有顺序的。

      也就是说,收购一件物品所得到的“未来利润”并不能当作现在的经费来用。

    (2)“缴税”是在卖东西的时候,收购的时候并不会在经费中扣除税(c[i])。

      相当于从“未来利润”中扣除c[i]

 

  表示状态:

    dp[i][j] = max wealth(未来利润)

    i:考虑到第i种物品

    j:当前花的经费

 

  找出答案:

    max dp[i][j] - j

 

  如何转移:

    无限背包,正着枚举j。

    花费为c[i],价值为w[i] - c[i]。

    dp[i][j] = max(dp[i-1][j], dp[i-1][j-c[i]] + w[i])

 

  边界条件:

    dp[0][0] = m

    others = -1

 

AC Code:

 1 // state expression:
 2 // dp[i][j] = max wealth
 3 // i: considering ith goods
 4 // j: present cost
 5 //
 6 // find the answer:
 7 // max dp[i][j] - j
 8 //
 9 // transferring:
10 // dp[i][j] = max(dp[i-1][j], dp[i-1][j-c[i]] + w[i])
11 //
12 // boundary:
13 // dp[0][0] = m
14 // others = -1
15 #include <iostream>
16 #include <stdio.h>
17 #include <string.h>
18 #define MAX_N 105
19 #define MAX_M 1000005
20 
21 using namespace std;
22 
23 int n,m;
24 int ans;
25 int c[MAX_N];
26 int w[MAX_N];
27 int dp[MAX_M];
28 
29 void read()
30 {
31     cin>>n>>m;
32     for(int i=0;i<n;i++)
33     {
34         cin>>c[i]>>w[i];
35     }
36 }
37 
38 void solve()
39 {
40     ans=m;
41     memset(dp,-1,sizeof(dp));
42     dp[0]=m;
43     for(int i=0;i<n;i++)
44     {
45         for(int j=0;j<=m;j++)
46         {
47             if(j-c[i]>=0 && dp[j-c[i]]!=-1)
48             {
49                 dp[j]=max(dp[j],dp[j-c[i]]+w[i]-c[i]);
50             }
51             ans=max(ans,dp[j]-j);
52         }
53     }
54 }
55 
56 void print()
57 {
58     cout<<ans<<endl;
59 }
60 
61 int main()
62 {
63     read();
64     solve();
65     print();
66 }

 

posted @ 2017-08-31 23:42  Leohh  阅读(178)  评论(0编辑  收藏  举报