题目链接:https://www.luogu.org/problemnew/show/P1441
题目大意:有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。
思路:先用dfs枚举出要去掉的m个砝码,对于每种情况去dp出剩下的n-m个砝码最多有多少种不同重量。f[i][j]代表前 i-1个砝码能否组成重量j,其值为true or false。类似于01背包,简化为一维数组表示。
#include<bits/stdc++.h>
using namespace std;
const int maxn=25;
const int maxm=2010;
int n,m,ans,a[maxn];
bool f[maxm],vis[maxn];
void dp(){
memset(f,false,sizeof(f));
int sum=0,cnt=0;
f[0]=true;
for(int i=0;i<n;i++){
if(vis[i]) continue;
for(int j=sum;j>=0;j--){ //不能包含被自己更新过的状态
if(f[j]&&!f[j+a[i]]){
f[j+a[i]]=true;
cnt++;
}
}
sum+=a[i];
}
ans=max(ans,cnt);
}
void dfs(int idx,int num){
if(num>m) return;
if(num==m){
dp();
return;
}
for(int i=idx;i<n;i++){
if(!vis[i]){
vis[i]=true;
dfs(i+1,num+1);
vis[i]=false;
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>a[i];
}
dfs(0,0);
cout<<ans<<endl;
}