1. 程式人生 > >洛谷P1441 砝碼稱重 列舉 + 01揹包

洛谷P1441 砝碼稱重 列舉 + 01揹包

顯然,n<=20, m<=4 的資料範圍一眼爆搜。
直接搜尋一下不用哪4個砝碼,再做一遍01揹包即可。
可能是本人太菜雞,01揹包部分調了半天QAQ……

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 2002;
int ans,n,target,sumv, w[30];
bool f[maxn], mark[30];
inline int solve()
{
    memset
(f,0,sizeof(f)); int fin = 0, tot = 0; for(int i = 1;i <= n;++i) { if(mark[i])continue; tot += w[i]; for(int j = sumv;j >= w[i];--j)if(f[j-w[i]])f[j] = 1; f[w[i]] = 1; } for(int i = 1;i <= tot; ++i)if(f[i]) ++ fin; return fin; } void dfs(int
nums,int cur) { if(nums == target) { ans = max(ans,solve()); return; } for(int i = cur + 1;i <= n;++i) { mark[i] = 1; dfs(nums + 1, i); mark[i] = 0; } } int main() { // freopen("input.txt","r",stdin); scanf("%d%d",&n,&target); for
(int i = 1;i <= n;++i) { scanf("%d",&w[i]); sumv += w[i]; } if(target == 0){printf("%d",solve());return 0;} for(int i = 1;i <= n;++i) { mark[i] = 1; dfs(1,i); mark[i] = 0; } printf("%d",ans); return 0; }