突然想起之前听的 错误的剪枝不如不剪
切身体会到了
写了一行完全错误的剪枝(仍然没想明白
剪枝去掉之后就TLE的很惨
改写背包吧
wa了两个点
蒙被子里哭的特别伤心
早上起来订正
又颓了很久
数数日子快要不到两个月了
搜索版本:
#include<string.h>
#include<cstdio>
#include<iostream>
using namespace std;
template <typename T> void read(T &x){
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
x*=f;
}
int n,m;
int a[210];
int ans;
bool vis[210];
void dfs(int k,int d,int last){
if(ans==m) return;
if(abs(ans-m)>abs(d-m)) ans=d;
if(k==n+1) return;
for(int i=last+1;i<=n;++i){
if(!vis[i]){
if(a[i]+d<=m||abs(ans-m)>abs(d+a[i]-m)){
vis[i]=1;
dfs(k+1,d+a[i],i);
vis[i]=0;
}
}
}
}
int main(){
read(n),read(m);
for(int i=1;i<=n;++i) read(a[i]);
memset(vis,0,sizeof(vis));
ans=0;dfs(1,0,0);
cout<<ans<<endl;
return 0;
}
背包版本:
#include<string.h>
#include<cstdio>
#include<iostream>
using namespace std;
template <typename T> void read(T &x){
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
x*=f;
}
int n,m;
int a[210];
bool f[60010];
int sum=0;
int main(){
read(n),read(m);
for(int i=1;i<=n;++i){
read(a[i]);
sum+=a[i];
}
//cout<<sum<<endl;
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i<=n;++i)
for(int j=sum;j>=a[i];--j){
if(f[j]||f[j-a[i]]) f[j]=1;
}
//for(int i=1;i<=sum;++i) cout<<f[i]<<" "; cout<<endl;
int now=sum;
int ans=0;
for(int i=1;i<=sum;++i){
//cout<<f[i]<<" "<<abs(i-m)<<endl;
if(f[i]&&abs(i-m)<now){
now=abs(i-m);
ans=i;
}
if(abs(i-m)>now) break;
//cout<<now<<" "<<ans<<" "<<endl;
}
cout<<ans<<endl;
return 0;
}