本题为一道深度优先搜索题,每场比赛有看和不看两种状态,所以可以写一个函数
dfs(int k,long long sum),k表示第k场比赛,sum表示当前费用总和,时间复杂度为2的n次方。
题中N<=40,因此直接搜索会超时,所以可以通过折半搜索进行优化。
即将所有比赛分为两部分,对这两部分分别进行搜索,将产生的花费分别保存起来,最后再将两部分结果合并起来,得到答案。
具体代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[50],n,m;
vector<ll> fir,sec;
void dfs1(int k,ll sum){
if(k==n/2+1){
fir.push_back(sum);
return;
}
dfs1(k+1,sum);
dfs1(k+1,sum+a[k]);
}
void dfs2(int k,ll sum){
if(k==n+1){
sec.push_back(sum);
return;
}
dfs2(k+1,sum);
dfs2(k+1,sum+a[k]);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
dfs1(1,0);
dfs2(n/2+1,0);
sort(fir.begin(),fir.end());
ll ans=0;
for(int i=0;i<(int)sec.size();i++){
ans+=upper_bound(fir.begin(),fir.end(),m-sec[i])-fir.begin();//二分查找fir中小于等于m-sec[i]的方案数量
}
cout<<ans<<endl;
return 0;
}