洛谷 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;
}
凡所不能将我击倒的,都将使我更加强大