codeforces 1428G1 分组背包版本

include

include

include

include

include

include

include

using namespace std;
typedef long long ll;

const int maxn = 1000000;

int k,m,num,cntf,cntg;
int di[maxn];
ll n,F[10],f[21][maxn],g[maxn],v[1000],w[1000],vg[1000],wg[1000];

int qsm(int i,int po){
int res = 1;
while(po){
if(po&1) res *= i;
po >>= 1;
i *= i;
}
return res;
}

ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s10+ch-'0'; ch=getchar(); } return sf; }

int main(){
num = 0;
k = read();
int K = k-1;
int t = 0;
while(K - (1<<t) > 0){ // 二进制分组
di[++num] = 1<<t;
K -= (1<<t);
++t;
}
di[++num] = K;
// for(int i=1;i<=num;++i) printf("%d ",di[i]); printf(" ");

for(int i=0;i<6;++i) F[i] = read();
m = read();


n = read();

cntg = 0;
for(int d=1;d<=6;++d){ // 分组 dp 
	cntf = 0;
	v[++cntf] = 0, w[cntf] = 0;
	for(int i=1;i<=3;++i){
		ll wei = 1ll * (3*i) * qsm(10,d-1);
		ll val = 1ll * i * F[d-1];
		
		for(int j=1;j<=num;++j){
			v[++cntf] = 1ll * di[j] * val;
			w[cntf] = 1ll * di[j] * wei;
		}
	
	}
	
	memset(f,0,sizeof(f));
	for(int i=1;i<=cntf;++i){
		for(int p=1;p<=num;++p){
			for(int j=n;j>=0;--j){	
				if(j-w[i]>=0 ) f[p][j] = max(f[p][j],f[p-1][j-w[i]] + v[i]);
			}
		}
	}
	
	for(int i=1;i<=n;++i){
		if(f[num][i] != -1){
			vg[++cntg] = f[num][i];
			wg[cntg] = i;
		}
	}
}

vg[++cntg] = 0, wg[cntg] = 0;
	for(int i=1;i<=cntg;++i){
			printf("%lld %lld
",wg[i],vg[i]);
		}printf("
");	 

memset(g,-1,sizeof(g));
g[0] = 0;
for(int i=1;i<=cntg;++i){
	for(int j=n;j>=0;--j){
		if(j-wg[i]>=0 && g[j-wg[i]]!=-1) g[j] = max(g[j],g[j-wg[i]] + vg[i]);
	}
}

ll ans = 0;
for(int x=0;x<=n;x++){
	int tmp = x, o = 1;
	ll ta = 0;
	while(tmp > 0){
		if((tmp%10) % 3 == 0){
			ta += 1ll * (tmp % 10)/3 * F[o-1];
		}
		tmp /= 10;
		++o;
	}
	ans = max(ans,g[n-x]+ ta); //
}

printf("%lld
",ans);

return 0;

}

原文地址:https://www.cnblogs.com/tuchen/p/13855765.html