zoukankan      html  css  js  c++  java
  • UVA 10817

    题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=20&page=show_problem&problem=1758

    状态压缩的DP,dp[i][st]表示状态为st考虑后面i个人所有人最小花费,

    因为每个科目有三种状态,可以用一个三进制数表示,

    状态不是很多,所以可以把预先把每个数的三进制预处理出来,

    决策为选和不选。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxs = 8;
    const int MAXSTA = 6561+5;
    const int maxn = 101;
    int base[maxs+1],trp[MAXSTA][maxs+1];
    int dp[maxn][MAXSTA];
    int tch[maxn],cost[maxn],sa;
    int s,m,n;
    const int INF = 0x3fffffff;
    void preDeal()
    {
        base[0] = 1;
        for(int i = 1; i <= maxs; i++){
            base[i] = 3*base[i-1];
        }
        for(int i = 1; i < MAXSTA; i++){
            int x = i, cnt = 0;
            while(x){
                trp[i][cnt++] = x%3;
                x /= 3;
            }
        }
    }
    
    int dfs(int i,int st)
    {
        if(i == n) return st == sa? 0:INF;
        int &ans = dp[i][st];
        if(~ans) return ans;
        ans = dfs(i+1,st);
        //int nst = st;
        for(int j = 0; j < s; j++){
            if(trp[tch[i]][j] && trp[st][j] != 2){
                st += base[j];
            }
        }
        ans = min(ans,dfs(i+1,st)+cost[i]);
        return ans;
    }
    
    int work()
    {
        sa = base[s]-1;
        int st = 0,sum = 0;
        for(int i = 0; i < m; i++){
            int c; scanf("%d",&c);
            sum += c;
            while(getchar()!='
    '){
                int sub = getchar()-'1';
                int t = trp[st][sub] ;
                if(t != 2){
                    st += base[sub];
                }
            }
        }
        for(int i = 0; i < n; i++){
            scanf("%d",cost+i);
            tch[i] = 0;
            while(getchar()!='
    '){
                tch[i] += base[getchar()-'1'];
            }
        }
        memset(dp,-1,sizeof(dp));
        return sum + dfs(0,st);
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        preDeal();
        while(scanf("%d%d%d",&s,&m,&n),s){
            printf("%d
    ",work());
        }
        return 0;
    }
  • 相关阅读:
    Java异常简介
    Java中的接口
    Java中的抽象类
    Java的多态
    关于this
    面向对象的继承方式详解
    1像素边框问题
    HTML5之本地存储SessionStorage
    js数组去重的4个方法
    前端模块化
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4746428.html
Copyright © 2011-2022 走看看