RQNOJ 57 找啊找啊找GF:01背包

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

题意:

  sqybi在七夕这天太无聊了,所以他想去给自己找GF。

  总共有n个MM。

  搞定第i个MM要花费rmb[i]块大洋、rp[i]的人品、tim[i]的时间。

  现在sqybi有m块大洋、r个人品。

  问你在泡到MM的数量最多的情况下,所用的最短时间是多少。

题解:

  表示状态:

    dp[i][j][k][p] = min cost time

    i:考虑到第i个MM

    j:花费的rmb

    k:花费的rp

    p:已经搞定的MM数量

  找出答案:

    最多找到max_gf个GF。

    ans = min dp[n][j][k][max_gf]

  如何转移:

    now: dp[i][j][k][p]

    dp[i+1][j][k][p] = min dp[i][j][k][p] (不选)

    dp[i+1][j+rmb[i]][k+rp[i]][p+1] = min dp[i][j][k][p] + tim[i] (选)

    同时每次更新max_gf的值。

  边界条件:

    dp[0][0][0][0] = 0

AC Code:

 1 // state expression:
 2 // dp[i][j][k][p] = min cost time
 3 // i: considering ith MM
 4 // j: cost rmb
 5 // k: cost rp
 6 // p: get k GF
 7 //
 8 // find the answer:
 9 // min dp[n][0 to m][0 to r][max p]
10 //
11 // transferring:
12 // now: dp[i][j][k][p]
13 // dp[i+1][j][k][p] = min dp[i][j][k][p]
14 // dp[i+1][j+rmb[i]][k+rp[i]][p+1] = min dp[i][j][k][p] + tim[i]
15 // max_gf = max p
16 //
17 // boundary:
18 // dp[0][0][0][0] = 0
19 // others = -1
20 #include <iostream>
21 #include <stdio.h>
22 #include <string.h>
23 #define MAX_N 105
24 #define MAX_M 105
25 #define MAX_R 105
26 #define INF 10000000
27 
28 using namespace std;
29 
30 int n,m,r;
31 int ans;
32 int max_gf;
33 int rmb[MAX_N];
34 int rp[MAX_N];
35 int tim[MAX_N];
36 int dp[MAX_M][MAX_R][MAX_N];
37 
38 void read()
39 {
40     cin>>n;
41     for(int i=0;i<n;i++)
42     {
43         cin>>rmb[i]>>rp[i]>>tim[i];
44     }
45     cin>>m>>r;
46 }
47 
48 void solve()
49 {
50     max_gf=0;
51     memset(dp,-1,sizeof(dp));
52     dp[0][0][0]=0;
53     for(int i=0;i<n;i++)
54     {
55         for(int j=m;j>=0;j--)
56         {
57             for(int k=r;k>=0;k--)
58             {
59                 for(int p=max_gf;p>=0;p--)
60                 {
61                     if(dp[j][k][p]!=-1)
62                     {
63                         if(j+rmb[i]<=m && k+rp[i]<=r)
64                         {
65                             if(dp[j+rmb[i]][k+rp[i]][p+1]==-1 || dp[j+rmb[i]][k+rp[i]][p+1]>dp[j][k][p]+tim[i])
66                             {
67                                 dp[j+rmb[i]][k+rp[i]][p+1]=dp[j][k][p]+tim[i];
68                                 max_gf=max(max_gf,p+1);
69                             }
70                         }
71                     }
72                 }
73             }
74         }
75     }
76     ans=INF;
77     for(int j=0;j<=m;j++)
78     {
79         for(int k=0;k<=r;k++)
80         {
81             if(dp[j][k][max_gf]!=-1) ans=min(ans,dp[j][k][max_gf]);
82         }
83     }
84 }
85 
86 void print()
87 {
88     cout<<ans<<endl;
89 }
90 
91 int main()
92 {
93     read();
94     solve();
95     print();
96 }

 

原文地址:https://www.cnblogs.com/Leohh/p/7460904.html