为什么每次转移的时候不是必须修改g(i)而是取max
代码(取max,100pts):
#include<bits/stdc++.h>
using namespace std;
int n,maxn,w[25],f[(1<<18)+10],g[(1<<18)+10];
int main(){
cin>>n>>maxn;
for(int i=0;i<n;i++){
cin>>w[i];
}
memset(f,0x3f,sizeof(f));
f[0]=1;
g[0]=maxn;
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(i&(1<<j)) continue;
if(g[i]<w[j]&&f[i|(1<<j)]>=f[i]+1){
f[i|(1<<j)]=f[i]+1;
g[i|(1<<j)]=max(maxn-w[j],g[i|(1<<j)]);
}
else if(f[i|(1<<j)]>=f[i]){
f[i|(1<<j)]=f[i];
g[i|(1<<j)]=max(g[i]-w[j],g[i|(1<<j)]);
}
}
}
cout<<f[(1<<n)-1]<<endl;
return 0;
}
(强制修改,67pts):
#include<bits/stdc++.h>
using namespace std;
int n,maxn,w[25],f[(1<<18)+10],g[(1<<18)+10];
int main(){
cin>>n>>maxn;
for(int i=0;i<n;i++){
cin>>w[i];
}
memset(f,0x3f,sizeof(f));
f[0]=1;
g[0]=maxn;
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(i&(1<<j)) continue;
if(g[i]<w[j]&&f[i|(1<<j)]>=f[i]+1){
f[i|(1<<j)]=f[i]+1;
g[i|(1<<j)]=maxn-w[j];
}
else if(f[i|(1<<j)]>=f[i]){
f[i|(1<<j)]=f[i];
g[i|(1<<j)]=g[i]-w[j];
}
}
}
cout<<f[(1<<n)-1]<<endl;
return 0;
}