牛牛去買球 思維+揹包

鏈接:https://acm.nowcoder.com/acm/problem/21668
來源:牛客網
 

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 524288K,其他語言1048576K
64bit IO Format: %lld

題目描述

一個人如果在他很小的時候就自己賺過錢,他的一生都會過得非常節儉,因爲他知道財富來之不易.

作爲一個勤儉節約的好孩子,牛牛決定在生活中踐行這一原則.

有一天他想去商店買一些球來玩,他發現商店裏有n個盒子,每個盒子外面有一張標籤告訴你有ai個紅球,bi個藍球,需要ci的錢購買

但是由於店主是一個粗心的人,他告訴你每個盒子球的總量是符合標籤的說明的,但是具體的種類可能會有如下偏差,比如可能有

(ai+1 ,bi-1),(ai, bi), (ai-1, bi+1)三種可能

牛牛 想要買至少K個同顏色的球,但是他又不想浪費錢.

幫他算算最少花多少錢買盒子能夠使得至少會有K個球是同色的

輸入描述:

第一行輸入兩個整數n,K (1≤ n≤50, 1 ≤ K ≤ 10000)

第二行輸入n個整數表示a數組

第三行輸入n個整數表示b數組

第三行輸入n個整數表示c 數組

1 ≤ ai,bi,ci ≤ 10000

輸出描述:

輸出一個整數,如果無法達成目的,輸出$-1$

示例1

輸入

複製

2 10
6 5
4 4
1 1

輸出

複製

2

示例2

輸入

複製

2 10
5 5
4 4 
1 1

輸出

複製

-1

示例3

輸入

複製

1 9
10
5
13

輸出

複製

13

示例4

輸入

複製

5 10
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

輸出

複製

10

示例5

輸入

複製

5 17
1 2 3 4 15
1 2 3 4 5
1 2 3 4 5

輸出

複製

9

思路:我們很容易把它轉換爲揹包問題,揹包的容量爲球的個數,揹包的價值爲所取的價值,因爲要求取的某種球的個數大於等於k,我們考慮兩種極限情況:①:每個盒子裏的紅球都是ai-1個;②:每個盒子裏的藍球都是bi-1個。因爲dp[i]表示放了i個球所獲得的價值,因此我們就遍歷dp[k]到dp[20000-2](爲什麼是這個數呢?因爲最極限的情況是一共兩個盒子,盒子裏球的個數爲10000-1),取最小值。但是這樣就可以了嗎?並不是,樣例1告訴你了錯誤之處。我們考慮最普遍的情況,什麼情況某個顏色的球一定有大於等於k個呢?答案是取的取球總數大於等於2k-1時,一定有一個顏色的球個數大於等於k。因此我們就取這個盒子裏的球總數,不管其顏色。遍歷dp[2k-1]到dp[20000-2],取最小值。最終的最小值即答案。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+100;
const int inf=0x3f3f3f3f;
int a[55],b[55],c[55],dp[maxn];
int main()
{
	int n,k,ans,v=2e4-2;
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) scanf("%d",&b[i]);
	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
	memset(dp,inf,sizeof(dp));
	dp[0]=0;ans=inf;
	for(int i=1;i<=n;i++)
		for(int j=v;j>=(a[i]-1);j--)
			dp[j]=min(dp[j],dp[j-(a[i]-1)]+c[i]);
	for(int i=k;i<=v;i++) ans=min(ans,dp[i]);
	memset(dp,inf,sizeof(dp));
	dp[0]=0;
	for(int i=1;i<=n;i++)
		for(int j=v;j>=(b[i]-1);j--)
			dp[j]=min(dp[j],dp[j-(b[i]-1)]+c[i]);
	for(int i=k;i<=v;i++) ans=min(ans,dp[i]);
	memset(dp,inf,sizeof(dp));
	dp[0]=0;
	for(int i=1;i<=n;i++)
		for(int j=v;j>=(a[i]+b[i]);j--)
			dp[j]=min(dp[j],dp[j-(a[i]+b[i])]+c[i]);
	for(int i=2*k-1;i<=v;i++) ans=min(ans,dp[i]);
	if(ans==inf) puts("-1");
	else printf("%d\n",ans);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章