zoukankan      html  css  js  c++  java
  • hihoCoder week8 状态压缩·一

    状态压缩  写了两个半小时  太菜了

    题目链接 https://hihocoder.com/contest/hiho8/problem/1

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 10;
    const int MAXN = 1<<11;
    int n, m, q, w[MAXN];
    
    // 存取到达i时候, 前面m-1个的状态
    int dp[1024][MAXN];
    
    int Count(int x)
    {
        int cnt = 0;
        while(x) {
            cnt += x%2;
            x/=2;
        }
        return cnt;
    }
    
    void print(int tmp)
    {
        int mx = 0;
        for(int st=0; st<(1<<m); st++) {
            mx = max(mx, dp[tmp][st]);
        }
        cout << mx <<endl;
    }
    
    void printAll()
    {
        for(int i=0;i<n;i++) {
            print(i);
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        scanf("%d %d %d", &n, &m, &q);
        for(int i=0; i<n; i++) {
            scanf("%d", &w[i]);
        }
        // 第0个选就是0 第0个不选就是 w[0]
        dp[0][0] = 0; dp[0][1] = w[0];
        for(int i=1; i<n; i++) {
            if(i < m) {
                // 前m个很好转移,就是 dp[i][st] = dp[i-1][st]; 
                // 记录前i-1个的状态的最优值  如果当前i能插入  就更新最优值
                for(int st=0; st<(1<<(i)); st++) {
                    dp[i][st] = max(dp[i][st], dp[i-1][st]); 
                    if(Count(st) < q && (1&(st>>i))==0 ) {
                        dp[i][st+(1<<i)] = max(dp[i][st+(1<<i)], dp[i][st] + w[i]);
                    }
                }
            }
            else {
                // 之前的记录的是 [i-m+1, i]
                // 现在需要更新成 [i-m+2, i+1] 
                // 所以整体 i-m+1位不需要了  就是 dp[i][st>>1] = dp[i-1][st]
                for(int st=0; st < (1<<m); st++) {
                    dp[i][st>>1] = max(dp[i][st>>1], dp[i-1][st]);
                }
            
                // 由于此时i>=m了 保证之前肯定有m-1个状态, 所以前m-1个状态 分别在[0, m-2]之间
                // 因而此时的i 应该放在 m-1 位, 然后可以插入i, 就更新最优值
                for(int st=0; st<(1<<m); st++) {
                    //int k = i%m + 1;
                    int k = m-1;
                    if(Count(st) < q && (1 & (st >> k))==0) {
                        dp[i][st+(1<<k)] = max(dp[i][st+(1<<k)], dp[i][st] + w[i]);
                    }
                }
            }
        }
        //printAll();
        print(n-1);
        return 0;
    }
  • 相关阅读:
    Redis其他命令
    Redis 键(key)
    Redis数据类型命令
    配置命令 CONFIG
    Redis简介
    idea破解
    jenkins+allure+testng
    Jenkins
    docker镜像
    docker命令
  • 原文地址:https://www.cnblogs.com/Draymonder/p/9976845.html
Copyright © 2011-2022 走看看