Diversity

Atcoder Beginner Contest 383 F

Problem Statement

一家商店里有 $N$ 种商品出售。 $i$ (件)产品的价格为 $P_i$ 日元,效用值为 $U_i$ ,颜色为 $C_i$ 。

你将从这些 $N$ 产品中选择一个子集购买(可能一个都不)。所选商品的总价最多为 $X$ 日元。

您的满意度为 $S + T \times K$ ,其中 $S$ 是所选产品的效用总和, $T$ 是所选产品中不同颜色的数量。这里, $K$ 是一个给定的常数。

您选择的产品将使您的满意度最大化。求最大满意度。

Constraints

  • $1 \leq N \leq 500$
  • $1 \leq X \leq 50000$
  • $1 \leq K \leq 10^9$
  • $1 \leq P_i \leq X$ $(1 \leq i \leq N)$
  • $1 \leq U_i \leq 10^9$ $(1 \leq i \leq N)$
  • $1 \leq C_i \leq N$ $(1 \leq i \leq N)$
  • All input values are integers.

Input

The input is given from Standard Input in the following format:

$N$ $X$ $K$

$P_1$ $U_1$ $C_1$

$P_2$ $U_2$ $C_2$

$\vdots$

$P_N$ $U_N$ $C_N$

Output

Print the answer.

Solving

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const int N = 505;
const int M = 5e4+100; 
struct node
{
    int cost,val,color;
    bool operator<(const node &another) const
    {
        return color < another.color;
    }
}arr[N]; 
int dp[N][M];//在第i件商品下有j元的情况下最多可以获得多少满意度
int n,m,k;
void solve()
{
    cin >> n >> m >> k;
    for(int i=1;i<=n;i++)
    {
        cin >> arr[i].cost >> arr[i].val >> arr[i].color;
    }
    sort(arr+1,arr+1+n);
    for(int i=1,ptr=0;i<=n;i++)
    {   
        // case 1 : 当前的钱不足以购买此商品 此时状态不变即还等于遍历到上个物品时的状态 dp[i][j] = dp[i-1][j]
        for(int j=1;j<arr[i].cost;j++)
        {
            dp[i][j] = dp[i-1][j];
        }
        // case 2 : 当前的钱可以购买此商品 需要在 不买(A) 买(B) 和 买一个新颜色的物件(C)
        for(int j=arr[i].cost;j<=m;j++)
        {
            dp[i][j] = max(
                {
                    dp[i-1][j],// choice A
                    dp[i-1][j-arr[i].cost] + arr[i].val,// choice B
                    dp[ptr][j-arr[i].cost] + arr[i].val + k// choice C
                    //每多一个颜色种类加一个K
                    // 从上一个颜色的最后一个物品转移过来
				    // 保证当前物品此时是当前颜色中第一个取的
                }
            );
        }
        //更新ptr
        if(arr[i].color!=arr[i+1].color)
        {
            ptr = i; // ptr表示上一个颜色的最后一个商品的位置。
        }
    }
    cout << dp[n][m];
}
Licensed under CC BY-NC-SA 4.0
Member of the Qilu University Of Technology ACM-ICPC Association
Built with Hugo
Theme Stack designed by Jimmy