zoukankan      html  css  js  c++  java
  • CDOJ 215 吴队长征婚 DFS+剪枝

    题目链接:

    http://acm.uestc.edu.cn/#/problem/show/215

    题意:

    题解:

    http://www.lai18.com/content/7765203.html
    剪枝1:大木棍长度只可能是sum的约数
    剪枝2:重复的木棍就可以不用枚举了
    剪枝3:每次都从最长的开始枚举

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define MS(a) memset(a,0,sizeof(a))
     5 #define MP make_pair
     6 #define PB push_back
     7 const int INF = 0x3f3f3f3f;
     8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     9 inline ll read(){
    10     ll x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 //////////////////////////////////////////////////////////////////////////
    16 const int maxn = 1e5+10;
    17 
    18 int n,a[70],sum,num,vis[70];
    19 
    20 bool cmp(int x,int y){
    21     return x > y;
    22 }
    23 
    24 bool dfs(int x,int y,int z,int len){
    25     if(x == num){
    26         return 1;
    27     }
    28 
    29     for(int i=z; i<n; i++){
    30         if(vis[i]) continue;
    31         // cout << x << " " << i << " " << y+a[i] << endl;
    32         if(y+a[i] == len){
    33             vis[i] = 1;
    34             if(dfs(x+1,0,0,len)) return 1; // 如果当前搜出了一个符合长度的,那么它肯定是一个合法的情况,就不需要拆它了
    35             vis[i] = 0;
    36             return 0; //如果当前这个木棒在合成后正好符合长度要求,但是之后的搜索确是失败的,说明后面也无法合成满足要求的木棒,也直接return false就可以
    37         }else if(y+a[i] < len){
    38             vis[i] = 1;
    39             if(dfs(x,y+a[i],i+1,len)) return 1; // 如果当前搜出了一个符合长度的,那么它肯定是一个合法的情况,就不需要拆它了
    40             vis[i] = 0;
    41             if(y==0) return 0; // 从长度为0开始dfs 最后回到了0,在这一层没有满足的,回溯
    42             while(a[i]==a[i+1]) i++; // 如果某个木棒在这个状态搜索失败,那所有与这个木棒相同长度的木棒就不用在这次搜索中搜索了
    43         }
    44     }
    45     return 0;
    46 }
    47 
    48 int main(){
    49     while(cin >> n, n){
    50         sum = 0;
    51         for(int i=0; i<n; i++){
    52             a[i] = read();
    53             sum += a[i];
    54         }
    55         sort(a,a+n,cmp);
    56         int len;
    57         for(len=a[0]; len<=sum; len++){ // 原长度肯定>=这些木棒的最大长度,而且能被所有木棒的总长度整除
    58             if(sum%len == 0){
    59                 num = sum/len;
    60                 // cout << "===" << num << endl;
    61                 MS(vis);
    62                 if(dfs(0,0,0,len))
    63                     break;
    64             }
    65         }
    66         cout << len << endl;
    67     }
    68 
    69     return 0;
    70 }
  • 相关阅读:
    C# 串口操作系列(4) -- 协议篇,文本协议数据解析(转)
    c#中,确保数据接收完整的 串口处理程序
    特别好的系列GMap.net技术总结文章12篇
    lock()
    获取程序启动路径去掉后面的i个字符
    wpf简单界面
    使用.NET进行高效率互联网敏捷开发的思考和探索【一、概述】
    $.getJSON 返回值、AJAX异步调用步骤
    JQuery validate 在IE兼容模式下出现 js错误(成员找不到)的修正:
    jQuery getJSON() 能给外部变量赋值
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827689.html
Copyright © 2011-2022 走看看