• 2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛) Chino with Queue(状压dp)


    链接:https://ac.nowcoder.com/acm/contest/553/C
    来源:牛客网

    题目描述

    Chino的数学很差,因此Cocoa非常担心。今天,Cocoa准备教Chino和排队有关的问题。
    我们总是会学各种排列组合的问题,那些题目大多数都是套路。而Cocoa不喜欢套路。
    通常来说,每个人在排队的时候都会对前一个人有所意见,而如果他们排在第一个,也会颇有微词。因此,排一个尽可能让更多人满意的队伍是一件难事。
    假设我们要给个人排队,表示了j排在i之前一个给i带来的舒适度,而就表示了i排在第一位的舒适度。
    通过一番模拟,Chino当然计算出了最优的方案,不过Cocoa希望Chino能计算地快一点。
    题目对于Chino来说太难啦,你能帮一帮Chino吗?

    输入描述:

    第一行是一个正整数n;接下来是一个n×nn×n的矩阵Wi,j

    输出描述:

    输出所有人舒适度之和的最大值
    示例1

    输入

    复制

    4

    1 2 3 4

    1 2 3 4

    1 2 3 4

    1 2 3 4

    输出

    复制

    13

    思路:我们可以用二进制的0/1序列 来表示队列的状态(n很小)  但是我们只知道序列不行 我们还需要知道该序列的最后一个数是什么 所以我们 用 dp[状态][该状态下最后一个为j]的最优忍耐度

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<stack>
    #include<bitset>
    #include<cstdlib>
    #include<cmath>
    #include<set>
    #include<list>
    #include<deque>
    #include<map>
    #include<queue>
    #define ll long long int
    using namespace std;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
    int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    int G[20][20];
    int dp[1<<19][20];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                cin>>G[i][j];
            }
        for(int i=1;i<(1<<n);i++){ //枚举状态 
            for(int j=0;j<n;j++)
                if(i&(1<<j)){ //如果当前点为1 
                    bool f=0;
                    for(int k=0;k<n;k++){ //找到当前状态其他任意一个1点作为j的前面一个人 
                        if(k==j) continue;
                        if(i&(1<<k)){
                            dp[i][j+1]=max(dp[i][j+1],dp[i^(1<<j)][k+1]+G[j+1][k+1]); //所以当前的状态就由前p个取反状态的最优状态转移得到 
                            f=1;
                        }
                    }
                    if(!f)
                        dp[i][j+1]=G[j+1][j+1];     //不然就是只有j为1 那就让他自己站第一个 
                }
                    
        }
        int ans=0;
        for(int i=1;i<=n;i++)
            ans=max(ans,dp[(1<<n)-1][i]);
        cout<<ans<<endl;
    }
  • 相关阅读:
    Java中使用Log4j记录错误、输出日志
    oracle 触发器的实例(转)
    [jsp学习笔记]servelt get post
    [winfrom]C#中使用SendMessage
    3)创建,测试,发布 第一个NET CORE程序
    DDL和DML 的区别
    [jsp学习笔记] jsp过滤器
    [jsp学习笔记] jsp基础知识 数据初始化、同步
    [jsp学习笔记]jstl标签的使用
    LiteORM-For-DotNet,我的第一个开源库……更新
  • 原文地址:https://www.cnblogs.com/wmj6/p/10663371.html
Copyright © 2020-2023  润新知