方法1:列举所有可能 (50分)会超时
dfs中一定要到x=n是,才判断ans是否++,到n了一组可能解才确定下来,到n了才是一种情况。
#include<iostream>
using namespace std;
int n,l,r;
int a[45];
int ans;
//int x,sum;
void dfs(int x,int sum){
if(x==n){ if(l<=sum&&sum<=r) ans++; return;}
dfs(x+1,sum+a[x]);
dfs(x+1,sum);
}
int main(){
cin>>n>>l>>r;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
dfs(0,0);
printf("%d",ans);
return 0;
}
方法2:dp
这个学习同学的代码写的,我开始不会23333
然后改了一..(点点的意思)
同学的第二层for 都是从 r 开始的;
for(int j=r;j>=a[i];j--)
p[j]=p[j]+p[j-a[i]];
我的是从 min(sum,r)
优化一....
p[J] 是选择【1~i】中的一些数,他们的和为 J 的方案数
#include<iostream>
#include<cmath>
using namespace std;
int a[1045],p[1045];
int n,l,r;
int main(){
cin>>n>>l>>r;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int sum=0;
p[0]=1;
for(int i=1;i<=n;i++){
sum+=a[i];
for(int j=min(sum,r);j>=a[i];j--)
p[j]=p[j]+p[j-a[i]];
}
int ans=0;
for(int i=l;i<=r;i++)
ans+=p[i];
cout<<ans;
return 0;
}