CodeForces 550B Preparing Olympiad(DFS回溯+暴力枚举)

来源:互联网 发布:轰炸手机号码软件 编辑:程序博客网 时间:2024/05/17 22:23

题目链接】:click here~~

题目大意

一组题目的数目(n<=15),每个题目有相应的难度,问你选择一定的题目(大于r个且小于l个)且选择后的题目里最小难度与最大难度差不小于x,求选择方案数。

解题思路】:

DFS+回溯。

先发一发比较拙的代码:

#include <bits/stdc++.h>using namespace std;const int N=1e5+10;int num[N],mum[N];int n,m,q,t,l,r;int top,ans,cnt;void dfs(int sum,int d,int x,int minn)///和,极值,当前循环,最小数{    if(sum>=l&&sum<=r&&d>=q) ans++;    if(sum>r) return;    ///if(sum<l) return;当前累加的sum可能小于l    for(int i=x;i<=n;++i)    {        dfs(sum+num[i],num[i]-minn,i+1,minn);    }}int main(){    while(cin>>n>>l>>r>>q)    {        ans=0;        memset(num,0,sizeof(num));        for(int i=1; i<=n; ++i) scanf("%d",&num[i]);        sort(num+1,num+1+n);        for(int i=1; i<=n; ++i)        {            dfs(num[i],0,i+1,num[i]);///为了参照最大和最小,引入最小数        }        printf("%d\n",ans);    }    return 0;}

继续补充暴力枚举~~:

#include <bits/stdc++.h>using namespace std;const int N=1e2;int num[N];int n,l,r,x;int main(){    scanf("%d%d%d%d",&n,&l,&r,&x);    int ans=0;    memset(num,0,sizeof(num));    for(int i=0; i<n; ++i) scanf("%d",&num[i]);    for(int s=0; s<(1<<n); ++s)    {        int cnt=0,sum=0;        int maxx=-1e8,minn=1e8;        for(int i=0; i<n; ++i)            if((s>>i)&1)///关键!            {                sum+=num[i];                maxx=max(num[i],maxx);                minn=min(num[i],minn);                cnt++;            }        if(cnt>=2&&maxx-minn>=x&&sum>=l&&sum<=r) ans++;    }    printf("%d\n",ans);    return 0;}


1 0