4800: [Ceoi2015]Ice Hockey World Championship(折半搜尋)
阿新 • • 發佈:2018-11-01
4800: [Ceoi2015]Ice Hockey World Championship
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 622 Solved: 311
[Submit][Status][Discuss]
Description
有n個物品,m塊錢,給定每個物品的價格,求買物品的方案數。
Input
第一行兩個數n,m代表物品數量及錢數 第二行n個數,代表每個物品的價格
Output
一行一個數表示購買的方案數 (想怎麼買就怎麼買,當然不買也算一種)
Sample Input
5 1000100 1500 500 500 1000
Sample Output
8HINT
Source
#include<bits/stdc++.h>
#define N 45
#define M 1000007
#define ll long long
using namespace std;
ll n,m,ans,cnt,mx,flag;
ll val[N],f[N][M];
inline ll read()
{
ll x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(x=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
void dfs(int k,ll sum)
{
if(sum>m) return;
if(k==n)
{
ans++;return;
}
dfs(k+1,sum);
dfs(k+1,sum+val[k+1]);
}
void dp()
{
f[0][m]=1;
for(int i=1;i<=n;i++) for(int j=0;j<=m;j++)
{
f[i][j]+=f[i-1][j]+f[i-1][j+val[i]];
}
for(int i=0;i<=m;i++) ans+=f[n][i];
}
int main()
{
//freopen("ly.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;i++) val[i]=read();
if(m<=1e6) dp();
else dfs(0,0);
printf("%lld\n",ans);
return 0;
}
80暴力 dfs+dp
/*
折半搜尋
*/
#include<bits/stdc++.h>
#define ll long long
#define N 55
using namespace std;
ll n,m,mid,cnta,cntb,ans;
ll w[N],suma[1<<21],sumb[1<<21];
inline ll read()
{
ll x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(x=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
inline void dfs(int l,int r,ll sum,ll a[],ll &cnt)
{
if(sum>m)return;
if(l>r)
{
a[++cnt]=sum;return;
}
dfs(l+1,r,sum+w[l],a,cnt);
dfs(l+1,r,sum,a,cnt);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)w[i]=read();;
mid=n/2;
dfs(1,mid,0,suma,cnta);
dfs(mid+1,n,0,sumb,cntb);
sort(suma+1,suma+1+cnta);
for(int i=1; i<=cntb; i++)
ans+=upper_bound(suma+1,suma+1+cnta,m-sumb[i])-suma-1;
printf("%lld\n",ans);
return 0;
}