洛谷 P3052

题目链接

点我跳转

题目大意

给出 \(n\) 个物品,第 \(i\) 个物品体积为 \(w_i\),现把其分成若干组,要求每组总体积 \(<=W\),问最小分组。\((n<=18)\)

解题思路

\(dp[i]\) 表示当前状态为 \(i\) 的最少分组数

\(sum[i]\) 表示把当前状态的所有人分到一个组需要的容量

\(sum[j] <= K\) 时,可以把状态 \(j\)(\(j\)\(i\)的子集) 的所有人分到一组,那么 \(dp[i] = min(dp[i] , dp[i - j] + 1)\)

AC_Code

#include<bits/stdc++.h>
using namespace std;
int dp[1 << 19] , sum[1 << 19];
int n , k , a[20];
signed main()
{
	memset(dp , 0x3f , sizeof(dp));
	dp[0] = 0;
	cin >> n >> k;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	for(int i = 1 ; i < (1 << n) ; i ++) 
	{
		for(int j = 1 ; j <= n ; j ++)
		{
			if(1 << (j - 1) & i) sum[i] += a[j];
		}
	}
	for(int i = 1 ; i < (1 << n) ; i ++)
	{
		for(int j = i ; j ; j = (j - 1) & i)
		{
			if(sum[j] > k) continue ;
			dp[i] = min(dp[i] , dp[i - j] + 1);
		}
	}
	cout << dp[(1 << n) - 1] << '\n';
	return 0;
}
posted @ 2020-12-22 23:16  GsjzTle  阅读(108)  评论(0编辑  收藏  举报