zoukankan      html  css  js  c++  java
  • HDU 5045 状压DP 上海网赛

    比赛的时候想的是把n个n个的题目进行状压 但这样不能讲究顺序,当时精神面貌也不好,真是挫死了

    其实此题的另一个角度就是一个n个数的排列,如果我对n个人进行状压,外面套一个按题目循序渐进的大循环,那么,在当前做第i个题目,前i-1个题目已经做完,然后做完的人的状态为j, j可能是1110 1101 1011什么的(假设已经做了三道题),因为我这样就可以只管状态而不管顺序了,我只取这种状态下的最大值,他究竟是怎么个顺序排列我不用管

    到此。。。好像问题就没有什么问题了,这种做法重复 m/n次最后把剩余的再跑一下就可以了,因为每次考虑第i个题的时候 只和i-1有关,则用个滚动数组即可,比较麻烦的是每次要清空,只能说空间和时间不可兼得啊

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    double A[11][1010];
    int n,m;
    double dp[2][1<<11];
    int main()
    {
        int t,kase=0;
        scanf("%d",&t);
        while (t--)
        {
            scanf("%d%d",&n,&m);
            for (int i=0;i<n;i++){
                for (int j=0;j<m;j++) scanf("%lf",&A[i][j]);
            }
            int ALL=1<<n;
            for (int i=0;i<=ALL;i++){
                dp[0][i]=dp[1][i]=0;
            }
            for (int i=0;i<n;i++){
                dp[0][1<<i]=A[i][0];
            }
            int p=0;
            double ans=0;
            for (int i=1;i<m;i++){
                p^=1;
                for (int j=0;j<=ALL;j++) dp[p][j]=0;
                for (int j=0;j<ALL;j++){
                    if (dp[p^1][j]==0) continue;
                    for (int k=0;k<n;k++){
                        if ((1<<k)&j) continue;
                        int nt=(1<<k)|j;
                        if (nt==ALL-1) nt=0;
                        dp[p][nt]=max(dp[p][nt],dp[p^1][j]+A[k][i]);
                        if (i==m-1) ans=max(ans,dp[p][nt]);
                    }
                }
            }
    
            printf("Case #%d: %.5lf
    ",++kase,ans);
        }
    }
  • 相关阅读:
    进程间多线程同步三种方法
    C++ 生成随机数 srand()和rand()
    事件对象用于多线程之间的同步
    $.ajax()方法参数详解
    面向对象的属性
    对多选框进行操作,输出选中的多选框的个数
    jQuery如何检查某个元素在网页上是否存在
    关于$.fn
    c#基础班笔记
    Sublime Text 3的快捷键
  • 原文地址:https://www.cnblogs.com/kkrisen/p/4001149.html
Copyright © 2011-2022 走看看