• hdu 1074动态压缩


    这题我一直以为是贪心做的,做了好久找不到规律

    看了解题报告,学习了压缩dp,类似dist,{v(i)}=min{v(i)-k},这种NP问题,O(n*2^n),数据给的比较小,其实也只能给15了,直接用2<<15数组表示状态

    每个状态,记录最优的pre,now,当然pre(上一个状态量)和now(当前节点值)是有关的,其实可以记录一个,最后递归输出now,有几个重要的过程注释在代码里了

    哎,最坑的是,解题报告看那什么,直接记住代码了,最后还记错了=.=,不过还好,debug的时候,算是更加了解过程了,不说了,这周可以恶刷dist了,其实koubin的算法更加类似dist,这个代码和之前的dp接近

    //状态压缩,用1111表示4中的取值情况,0000表示都不取,0001表示只取1
    //这里dp判断还是比较简单的,类似最短路径的,{V{i}} = min{V{i}-k}(k属于i中的集合)
    //这里路径小于0,这条路径损失的分数小于0,作0处理
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <string>
    
    using namespace std;
    const int MAXN = (1<<31)-1;
    typedef struct{
        string cn;
        int tm;
        int del;
    }course;
    typedef struct{
        int pre;
        int now;
        int tm;
        int red;
    }node;
    course a[16];
    node dp[1<<15];
    
    void init(){
        dp[0].pre = -1;
        dp[0].now = -1;
        dp[0].red = 0;
        dp[0].tm = 0;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                cin>>a[i].cn;
                scanf("%d%d",&a[i].del,&a[i].tm);
            }
            init();
            int tem = (1<<n)-1;
            for(int i=1;i<=tem;i++){
                dp[i].red = MAXN;
                for(int j=n-1;j>=0;j--){ //因为是按输入顺序字典序增加的,前优先,则前优先;比如0101->->1111,如果0101->1101->1111与0101->0111->1111代价相同,则A优先B
                    int s = 1<<j;         //这里我们判断离1111最近的取值,因为A比D先取了,所以D才是最靠近1111,则先取后段才是我们要求的前优先
                    if(i&s){
                        int past = i-s;
                        int red = dp[past].tm+a[j].tm-a[j].del;
                        if(red<0)red = 0;
                        if(dp[i].red>dp[past].red+red){
                            dp[i].red = dp[past].red+red;
                            dp[i].now = j;
                            dp[i].pre = past;
                            dp[i].tm = dp[past].tm+a[j].tm;
                        }
                    }
                }
            }
     
            cout<<dp[tem].red<<endl;
            stack <int >s1;
    
            while(tem){
                s1.push(dp[tem].now);
                tem = dp[tem].pre;
            }
            while(!s1.empty()){
                int tx = s1.top();
                s1.pop();
                cout<<a[tx].cn<<endl;
            }
           // cout<<"debug"<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code
    在一个谎言的国度,沉默就是英雄
  • 相关阅读:
    CC2431 代码分析⑦
    CC2431 代码分析 ⑤
    CC2431 代码分析⑥
    CC2431 代码分析④-衣锦还乡的CC2431
    基于CC2530/CC2430 的光强采集系统--ADC实验
    Server2012R2 ADFS3.0 The same client browser session has made '6' requests in the last '13'seconds
    Dynamics CRM2013 任务列表添加自定义按钮
    Dynamics CRM 2011/2013 section的隐藏
    Dynamics CRM2013 定制你的系统登录后的首页面
    Dynamics CRM EntityCollection 根据实体中的某个字段为依据去除重复数据
  • 原文地址:https://www.cnblogs.com/EdsonLin/p/5366270.html
Copyright © 2020-2023  润新知