• 22/5/21


    1,dfs剪枝:eg1:acwing 167.木棒;eg2:acwing 168.生日蛋糕;


    1,dfs剪枝:

    剪枝策略有四种,

    优化搜索顺序(多理解也要多想到),

    排除等效冗余(尽量不搜重复的),

    可行性剪枝;

    最优性剪枝;

    eg1:木棒;

    题意:

     要正确理解题意,实质是本题是找最小的组和同时使得各个组里的木棍的和相等;

    思路:枚举。把大木棍长从1开始枚举,然后再用给的小木棍长去拼凑大木棍长,如果能拼出来,说明这就是一合法解,且因为从小到大枚举,所以也是最小的大木棍长;

    剪枝方式:

    ①:可行性剪枝:只有当sum(所有小木棍的和)%大木棍的len==0时,才可以去拼凑;

    ②:优化搜索顺序,优先用大的拼,这样会及时找到不满足的情况从而return(这种技巧还挺常用的);

    ③:排除等效冗余:按组合顺序拼,所以可行的方式是按下标枚举小木棍的长度,然后用st[]数组标记用没用过;

    ④:本题特有的剪枝:当枚举的第一个小木棍长和最后一个小木棍长不符合时,直接return;

    1. #pragma GCC optimize(2)
    2. #include<bits/stdc++.h>
    3. #define rep1(i,a,n) for(register int i=a;i<n;++i)
    4. #define rep2(i,a,n) for(register int i=a;i<=n;++i)
    5. #define per1(i,n,a) for(register int i=n;i>a;i--)
    6. #define per2(i,n,a) for(register int i=n;i>=a;i--)
    7. #define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
    8. #define memset(a,i) memset((a),(i),sizeof (a))
    9. #define memcpy(a,i) memcpy((a),(i),sizeof (a))
    10. #define pro_q priority_queue
    11. #define pb push_back
    12. #define pf push_front
    13. #define endl "\n"
    14. #define lowbit(m) ((-m)&(m))
    15. #define YES cout<<"YES\n"
    16. #define NO cout<<"NO\n"
    17. #define Yes cout<<"Yes\n"
    18. #define No cout<<"No\n"
    19. #define yes cout<<"yes\n"
    20. #define no cout<<"no\n"
    21. #define yi first
    22. #define er second
    23. using namespace std;
    24. typedef pair<int,int> PII;
    25. typedef pair<long long,long long>PLL;
    26. typedef pair<int,PII> PIII;
    27. typedef long long ll;
    28. typedef double dob;
    29. const int N=70;
    30. int n;
    31. int w[N];
    32. int sum,len;
    33. int st[N];
    34. bool dfs(int u,int cur,int start)
    35. {
    36. if(u*len==sum)return 1;
    37. if(cur==len)return dfs(u+1,0,0);
    38. rep1(i,start,n)
    39. {
    40. if(st[i]||cur+w[i]>len)continue;
    41. st[i]=1;
    42. if(dfs(u,cur+w[i],i+1))return 1;
    43. st[i]=0;
    44. if(!cur||cur+w[i]==len)return 0;
    45. int j=i;
    46. while(j<n&&w[j]==w[i])j++;
    47. i=j-1;
    48. }
    49. return 0;
    50. }
    51. signed main()
    52. {
    53. quick_cin();
    54. while(cin>>n,n)
    55. {
    56. memset(st,0);
    57. sum=0;
    58. rep1(i,0,n)cin>>w[i],sum+=w[i];
    59. sort(w,w+n,greater<int>());
    60. len=1;
    61. while(1)
    62. {
    63. if(sum%len==0&&dfs(0,0,0))
    64. {
    65. cout<<len<<endl;
    66. break;
    67. }
    68. len++;
    69. }
    70. }
    71. return 0;
    72. }

    eg2:生日蛋糕;

    题意:
     思路:枚举r和h;

    优化:
    优化搜索顺序:①从下层到上层枚举;②:先枚举半径再枚举高;

    可行性剪枝:数学推导,(来自acwing random_srand );

     

     数学推导挺难想的,重在积累吧;

    1. #pragma GCC optimize(2)
    2. #include<bits/stdc++.h>
    3. #define rep1(i,a,n) for(register int i=a;i<n;++i)
    4. #define rep2(i,a,n) for(register int i=a;i<=n;++i)
    5. #define per1(i,n,a) for(register int i=n;i>a;i--)
    6. #define per2(i,n,a) for(register int i=n;i>=a;i--)
    7. #define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
    8. #define memset(a,i) memset((a),(i),sizeof (a))
    9. #define memcpy(a,i) memcpy((a),(i),sizeof (a))
    10. #define pro_q priority_queue
    11. #define pb push_back
    12. #define pf push_front
    13. #define endl "\n"
    14. #define lowbit(m) ((-m)&(m))
    15. #define YES cout<<"YES\n"
    16. #define NO cout<<"NO\n"
    17. #define Yes cout<<"Yes\n"
    18. #define No cout<<"No\n"
    19. #define yes cout<<"yes\n"
    20. #define no cout<<"no\n"
    21. #define yi first
    22. #define er second
    23. using namespace std;
    24. typedef pair<int,int> PII;
    25. typedef pair<long long,long long>PLL;
    26. typedef pair<int,PII> PIII;
    27. typedef long long ll;
    28. typedef double dob;
    29. const int N=25,inf=1e9;
    30. int n,m;
    31. int minv[N],mins[N];
    32. int R[N],H[N];
    33. int ans=inf;
    34. void dfs(int u,int v,int s)
    35. {
    36. if(v+minv[u]>n)return;
    37. if(s+mins[u]>=ans)return;
    38. if(s+2*(n-v)/R[u+1]>=ans)return;
    39. if(!u)
    40. {
    41. if(v==n)ans=s;
    42. return;
    43. }
    44. for(int r=min(R[u+1]-1,(int)sqrt(n-v));r>=u;r--)
    45. {
    46. for(int h=min(H[u+1]-1,(n-v)/r/r);h>=u;h--)
    47. {
    48. int t=0;
    49. if(u==m)t=r*r;
    50. R[u]=r,H[u]=h;
    51. dfs(u-1,v+r*r*h,s+2*r*h+t);
    52. }
    53. }
    54. }
    55. signed main()
    56. {
    57. quick_cin();
    58. cin>>n>>m;
    59. rep2(i,1,m)
    60. {
    61. minv[i]=minv[i-1]+i*i*i;
    62. mins[i]=mins[i-1]+2*i*i;
    63. }
    64. R[m+1]=H[m+1]=inf;
    65. dfs(m,0,0);
    66. if(ans==inf)ans=0;
    67. cout<<ans<<endl;
    68. return 0;
    69. }

     

  • 相关阅读:
    戏说领域驱动设计(十六)——实体概念
    Python图像和视频上传
    怎么将PNG, JPEG, GIF,BMP等格式图片转化为ICO格式文件?
    【Python算法】(一)递归:美术馆艺术大盗问题
    js获取对象值得方式(在不确定对象参数的情况下获取值)
    设计的思考,设计是什么? 优漫动游
    线性基学习
    深度学习 图像分割 PSPNet 论文复现(训练 测试 可视化)
    【C语言】结构体+位段+枚举+联合(2)
    动画沿椭圆路线进行旋转
  • 原文地址:https://blog.csdn.net/aidaqiudeaichao/article/details/124894353