牛客挑战赛34 A.能天使的愿望(分组背包)

题目

链接:https://ac.nowcoder.com/acm/contest/2271/A
来源:牛客网

在一条直线上均匀的分布着 N个店铺,每个店铺有 M 把铳出售,你不想自己出门买铳,所以打算网购(?)
在第 i 个店铺购买 j 把铳需要 Pi,j 元。如果在某商店购买了少于 Y 把铳,则每把铳需要额外支付 ai 元邮费,如果购买 Y 把及以上,则在这家店可以包邮。
另外,在每家店只能购买一次,也就是说你在每家店最多下一次订单
现在能天使想要 K 把铳,请问购买 K 把铳的最小花费是多少(总花费=总邮费+总购买费)?
当然,能天使并不喜欢铺张浪费,所以请不要购买超过 K 把铳,同时保证一定能够购买 K 把铳

输入描述:

输入

5 8 10 3
10 20 100 5 1
1 3 5 7 9 11 13 15
2 4 6 8 10 12 14 16
1 2 3 4 5 6 7 8
1 3 6 10 15 21 28 36
10 20 30 40 50 60 70 80

输出

12

思路:

分组背包,dp[i][j]表示前i组,最大花费j,可以取得的最小价值
dp[i][j] = min(dp[i-1][j],dp[i-1][j-u]+p[i][u])(1<=u<=M)

代码:

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=805;
int N,M,K,Y;
LL a[maxn],p[maxn][maxn];
LL dp[maxn][maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin>>N>>M>>K>>Y;
    for(int i=1;i<=N;i++)
        cin>>a[i];
    for(int i=1;i<=N;i++)
    {
        for(int j=1;j<=M;j++)
        {
            cin>>p[i][j];
            if(j<Y)
            {
                p[i][j]+=j*a[i];
            }
        }
        
    }
    memset(dp,0,sizeof(dp));
    for(int i=0;i<maxn;i++)
        dp[0][i]=INF;
    for(int i=1;i<=N;i++)
    {
        for(int j=0;j<=K;j++)
        {
            for(int u=1;u<=M;u++)
            {
                if(j>=u)
                    dp[i][j]=min(dp[i-1][j],dp[i-1][j-u]+p[i][u]);
            }
        }
    }
    cout << dp[N][K] << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wwwlps/p/11978320.html
今日推荐