• HDU 4620 Fruit Ninja Extreme(2013多校第二场 剪枝搜索)


    这题官方结题报告一直在强调不难,只要注意剪枝就行。

    这题剪枝就是生命....没有最优化剪枝就跪了:如果当前连续切割数加上剩余的所有切割数没有现存的最优解多的话,不需要继续搜索了

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    # define MAX 33
    using namespace std;
    
    struct node {
        int id,tim,total;
        int fr[11];
    }cuts[MAX];
    int n,m,w;
    int ans[MAX],final,tmp[MAX],vis[222];
    bool cmp (node a,node b) {
        return a.tim < b.tim;
    }
    
    void dfs(int v0,int step,int cur,int num) { // 源点,切割数,当前切割时间,已经切过的水果数
        if(step > final) {
            final = step;
            for (int i=0; i<step; i++) ans[i] = tmp[i];
        }
        if(step + n - v0 - 1 <= final) return; //最优化剪枝
        if(m - num < 3) return ; 
        int cnt = 0;
        for(int i=v0+1; i<n; i++) {
            if(cur == 0 || cuts[i].tim - cur <= w) { //cur为零时每个点作为第一刀都有可能
                cnt = 0;
                int erase[15]; //之前设为全局变量....各种跪
                for(int j=0; j<cuts[i].total; j++) {
                    if(vis[cuts[i].fr[j]] == 0) {
                        cnt ++;
                        erase[cnt] = cuts[i].fr[j];
                        vis[cuts[i].fr[j]] = 1;
                    }
                }
                if(cnt >= 3) {
                    tmp[step] = cuts[i].id;
                    dfs(i,step+1,cuts[i].tim,num + cnt);
                }
                for(int j=1; j<=cnt; j++) vis[erase[j]] = 0;
            }
        }
    }
    
    
    int main() {
        int T;
        cin >> T;
        while(T--) {
            scanf("%d%d%d",&n,&m,&w);
            for(int i=0; i<n; i++) {
                scanf("%d%d",&cuts[i].total,&cuts[i].tim);
                cuts[i].id = i+1;
                for(int j=0; j<cuts[i].total; j++) {
                    scanf("%d",&cuts[i].fr[j]);
                }
            }
            final = 0;
            memset(vis,0,sizeof(vis));
            sort(cuts,cuts+n,cmp);
            dfs(-1,0,0,0);
            printf("%d
    ",final);
            sort(ans,ans+final);
            for(int i=0; i<final; i++) {
                if(i != final -1)
                    printf("%d ",ans[i]);
                else printf("%d
    ",ans[final - 1]);
            }
        }
        return 0;
    }


  • 相关阅读:
    带你了解数据库的“吸尘器”:VACUUM
    基于深度学习的两种信源信道联合编码
    6大创新技术及2亿美元投入计划,这个活动有点料
    MindSpore实践:对篮球运动员目标的检测
    如何正确使用Python临时文件
    一段java代码是如何执行的?
    TensorFlow csv读取文件数据(代码实现)
    TensorFlow优化器及用法
    TensorFlow损失函数
    回归算法分类,常用回归算法解析
  • 原文地址:https://www.cnblogs.com/aukle/p/3228542.html
Copyright © 2020-2023  润新知