Loj #6560 小奇取石子

题面

 

    分类讨论一波,n小的暴力2^n,n大的背包。

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2505,inf=1e9,S=(1<<20)|1;

int f[N],n,m,a[205],k,ans;
int bt[S],sum[S];

inline void solve1(){
	for(int i=0;i<n;i++) sum[1<<i]=a[i];
	for(int i=1,all=(1<<n)-1,now;i<=all;i++){
		now=i&-i,bt[i]=bt[i^now]+1,sum[i]=sum[i^now]+sum[now];
		if(bt[i]<=m&&sum[i]<=k) ans=max(ans,sum[i]);
	}
}

inline void solve2(){
	fill(f+1,f+k+1,inf);
	
	for(int i=0;i<n;i++)
	    for(int j=k;j>=a[i];j--) if(f[j-a[i]]+1<f[j]) f[j]=f[j-a[i]]+1;
	    
	for(int i=k;i;i--) if(f[i]<=m){ ans=i; break;}
}

int main(){
	
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<n;i++) scanf("%d",a+i);
	
	if(n<=20) solve1(); else solve2();
	printf("%d\n",ans);
	
	return 0;
} 

  

posted @ 2019-01-28 11:28  蒟蒻JHY  阅读(327)  评论(0编辑  收藏  举报