zoukankan      html  css  js  c++  java
  • hdu1074

    hdu1074 Doing Homework
    传送门
    题意
    (n(1leq nleq 15))项作业,每项作业都有名称、提交截止日期和完成这项作业所花费的日期,逾期一天扣一分,计算完成所有作业所扣的分数的最小值,并且输出按照时间顺序完成的作业名称
    (n)项作业按照字典序从小到大输入,如果答案不唯一,输出字典序最小的解
    题解
    由于(n)不超过(15),可以通过状态压缩表示所有作业完成的状态,(1)表示已完成,(0)表示未完成
    从小到大枚举所有状态,对于每一种状态,枚举所有未完成的作业,设完成这一作业的状态为新状态,更新新状态最少的扣分以及是从哪个状态转移过来的
    由于作业是按照字典序从小到大排列的,更新的新状态是最后完成的作业,字典序最小的解是将字典序较大的作业放在后面,所以每次从后向前枚举所有作业
    从状态((1<<n)-1)到状态(0)逆向找到每一次完成的作业,可以确定完成作业的顺序
    时间复杂度(O(n*2^n))

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<cmath>
    #include<ctime>
    #include<climits>
    #include<algorithm>
    #define LL long long
    #define PII pair<int,int>
    #define PLL pair<LL,LL>
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lowbit(x) x&(-x)
    using namespace std;
    
    const int maxn=16;
    int T,n,dp[1<<maxn],last[1<<maxn],sum[1<<maxn];
    struct node{
        int d,cost;
        string name;
    }a[maxn];
    vector<string> ans;
    
    int main(){
        std::ios::sync_with_stdio(false);
        cin>>T;
        while(T--){
            cin>>n;
            for(int i=0;i<n;i++){
                cin>>a[i].name>>a[i].d>>a[i].cost;
            }
            memset(sum,0,sizeof(sum));
            int sta=1<<n;
            for(int i=0;i<sta;i++){
                for(int j=0;j<n;j++){
                    if(i&(1<<j)) sum[i]+=a[j].cost;
                }
            }
            memset(dp,0x3f,sizeof(dp));
            dp[0]=0;
            for(int i=0;i<sta;i++){
                for(int j=n-1;j>=0;j--){
                    if(i!=(i|(1<<j))){
                        if(dp[i|(1<<j)]>dp[i]+max(0,sum[i|(1<<j)]-a[j].d)){
                            dp[i|(1<<j)]=dp[i]+max(0,sum[i|(1<<j)]-a[j].d);
                            last[i|(1<<j)]=i;
                        }
                    }
                }
            }
            cout<<dp[sta-1]<<"
    ";
            int s=sta-1;
            ans.clear();
            while(s){
                int t=last[s];
                for(int i=0;i<n;i++){
                    if(((s>>i)&1)^((t>>i)&1)){
                        ans.push_back(a[i].name);
                        break;
                    }
                }
                s=t;
            }
            for(int i=n-1;i>=0;i--) cout<<ans[i]<<"
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    类的访问级别
    包和静态引入
    数组
    流程控制
    适合初学者的ROS机器人教程(3): ROS下使用Python对UR5机器人建模与控制
    适合初学者的强化学习教程(1): python使用gym实践和注意事项
    适合初学者的ROS机器人教程(1): Ubuntu下ROS创建自己的包和使用github下载的包
    适合初学者的ROS机器人教程(2): Ubuntu下ROS使用Gazebo和Rviz对UR5机器人建模
    spyder使用IPython的ipdb调试
    mysql创建外键
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13573932.html
Copyright © 2011-2022 走看看