dg+优化(裸递归60ots)
查看原帖
dg+优化(裸递归60ots)
680022
Rice_Demon_King楼主2024/9/7 18:38

我是因为标签是搜索才不用动归的,本代码仅供参考

见代码

//#pragma GCC optimize( 2 )
#include<bits/stdc++.h>
#define MAXN 109
#define For(i,j,k) for(int i=j;i<=k;++i)
#define dFor(i,j,k) for(int i=j;i>=k;--i)
#define ll long long
using namespace std;
int m,r,n,ans=0,a[MAXN],x[MAXN];
ll c(int n,int m){  //组合 
    ll cnt= 1;
    m=min(m,n-m);
    For(i,0,m-1){
        cnt*=(n-i);
        cnt/=(i+1);
    }
    return cnt;
}
void dg(int d,int now,int sum){   //d为枚举了第 d个,now为当前已取 now个,sum为当前权值和 
	if(d==m+1){
		if(now!=r) return ;
		if(sum<=n) return ;
		ans++;
	} 
	else{
		if(m-d+1+now<r) return ;	//后面全取也取不到 r个 
		if(now>r) return ;	//取多了
		if(now==r){
			if(sum<=n) return ; //不够了 
			else ans++;
			return ; 
		}
		if(sum>n){			//前面已经取够了,后面随便取 
			ans+=c(m-d+1,r-now);
			return ;
		}
		for(x[d]=0;x[d]<=1;x[d]++){
			if(x[d]==0){		//不取 
				if(m-d+now<r) continue;
				dg(d+1,now,sum);
			}
			else{		//取 
				if(now+1>r) continue;  
				dg(d+1,now+1,sum+a[d]);
			}
		}
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>m>>r>>n; 
	For(i,1,m) cin>>a[i];
	dg(1,0,0);
	cout<<ans;
	return 0;
}

只能说时间复杂度给3s确实仁慈了...

2024/9/7 18:38
加载中...