牛客挑战赛34 A题

能天使的愿望

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

输入描述:

第一行 4 个整数,N,M,K,Y
第二行 N 个整数,第 i 个数表示 ai
接下来 N 行,每行 M 个数,表示 Pi,j

输出描述:

一行一个非负整数,表示题目描述中的最小花费


01背包的进阶题吧;

前面部分跟01背包一样,不同的是我们不知道当选第一家店时,究竟要选那种铳,所以后面加层循环;

代码:

#include
#define LL long long
#define pa pair
#define lson k<<1
#define rson k<<1|1
#define inf 0x3f3f3f3f
//ios::sync_with_stdio(false);
using namespace std;
const int N=400100;
const int M=400100;
const LL mod=998244353;
LL a[1000];
LL p[1000][1000];
LL dp[1000];
int main(){
	ios::sync_with_stdio(false);
	int n,m,k,y;
	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]=p[i][j]+(LL)j*a[i];
			} 
		}
	}
	for(int i=1;i<=k;i++) dp[i]=2e17;
	for(int i=1;i<=n;i++){
		for(int j=k;j>=0;j--){//前面跟01背包相同 
			for(int q=1;q<=m;q++){//枚举出售几把 
				if(j>=q){
					dp[j]=min(dp[j],dp[j-q]+p[i][q]);
				}
			}
		}
	}
	cout<<dp[k]<<endl;
	return 0;
}```

你可能感兴趣的:(#,背包,01背包)