题解 [CEOI2015 Day2][LuoguP4799]世界冰球锦标赛
题目链接
数据范围 n ≤ 40 n \leq 40 n≤40,普通搜索会超时,选用折半搜索。
折半搜索的思路其他dalao已经讲得很清楚了,我来讲一讲一些细节。
先上代码。
//P4799
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
vector<ll> lv,rv; //存储每一种方案最终花费的钱
ll tic[50],n,m,ans,mid;
inline void dfs(ll l,ll r,ll sum,vector<ll> &v){
if(sum>m) return;
if(l>r) { v.push_back(sum); return; } //搜出了一种方案
dfs(l+1,r,sum+tic[l],v),dfs(l+1,r,sum,v); //选或不选
return;
}
int main(){
scanf("%lld%lld",&n,&m),mid=n>>1;
for(ll i=1; i<=n; ++i) scanf("%lld",&tic[i]);
dfs(1,mid,0,lv),dfs(mid+1,n,0,rv);
sort(lv.begin(),lv.end());
for(ll i=0; i<rv.size(); ++i)
ans+=upper_bound(lv.begin(),lv.end(),m-rv[i])-lv.begin();
printf("%lld",ans);
return 0;
}
一些要点:
-
vector
中存储的是每一种方案最终花费的钱 -
如果
l>r
,代表已经搜出了一种方案,就将这种方案最终花费的钱(sum
)放入对应的vector
中。 -
每一个物品有两种方案:选或不选