【bzoj4800】: [Ceoi2015]Ice Hockey World Championship dfs

【bzoj4800】: [Ceoi2015]Ice Hockey World Championship

N<=40所以如果直接dfs背包会TLE

考虑Meet-in-the-middle

如果把N个物品分成前后A B两段分别背包

分别在A B中可行的方案的花费记录在a b中

答案就是a[i]+b[j]<=M的个数

把a b排序 然后序列就是单调的了

两个指针扫一遍就好了

 /* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long ll n,m,mid,ans;
ll c[],a[][],ca[]; void dfs(int p,int x,ll cost){
if (cost>m) return;
if ((x>=mid && p==) || (x>=n && p==)){
a[p][++ca[p]]=cost;
return;
}
dfs(p,x+,cost+c[x+]);
dfs(p,x+,cost);
} int main(){
scanf("%lld%lld",&n,&m);
for (int i=;i<=n;i++) scanf("%lld",&c[i]);
mid=n/;
dfs(,,);
dfs(,mid,);
sort(a[]+,a[]+ca[]+);
sort(a[]+,a[]+ca[]+);
for (int l=,r=ca[];l<=ca[] && r>=;ans+=r,l++) while (a[][l]+a[][r]>m) r--;
printf("%lld\n",ans);
return ;
}

竟然有Rank4(2017.3.31)。。好快啊。。

上一篇:2、Flask实战第2天:URL传参


下一篇:[转]JavaScript和html5 canvas生成圆形印章