zoukankan      html  css  js  c++  java
  • 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
    在一个谎言的国度,沉默就是英雄
  • 相关阅读:
    poj2104 Kth-Number
    bzoj2120 数颜色
    hdu5145 NPY and girls
    bzoj2734 集合选数
    bzoj3732 NetWork
    bzoj2152 聪聪可可
    hdu2036(多边形面积)
    超大次幂思路
    hdu 2030 统计汉字个数
    Hibernate 配置文件与映射文件 总结
  • 原文地址:https://www.cnblogs.com/EdsonLin/p/5366270.html
Copyright © 2011-2022 走看看