zoukankan      html  css  js  c++  java
  • Vijos 1456 最小总代价 (状压dp)

    看到这道题n只有16,就可以想到状压dp

    每个人只有经过或者没经过,那就用1表示经过,0表示没经过

    但是不是当前在谁那里,所以再加一维来记录

    所以f[state][i]表示在物品在i,当前的状态是state情况下的最小总代价

    有几个细节要注意

    (1)刷表法。要提前初始化为-1,然后然后每个起点为0.。做的时候要判断当前状态存不存在。

    (2)之前状态存在,当前这个人不存在才可以去做。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    #define _for(i, a, b) for(int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXN = 20;
    int g[MAXN][MAXN], f[(1<<16)+10][MAXN], n;
    
    int main()
    {
    	scanf("%d", &n);
    	REP(i, 0, n)
    		REP(j, 0, n)
    			scanf("%d", &g[i][j]);
    	
    	memset(f, -1, sizeof(f));
    	REP(i, 0, n) f[1<<i][i] = 0;
    	
    	int ans = 1e9;
    	REP(i, 0, 1 << n)
    		REP(j, 0, n)
    			if(f[i][j] != -1)
    				REP(k, 0, n)
    					if(!(i & (1 << k)))
    					{
    						int& state = f[i | (1 << k)][k];
    						if(state == -1) state = f[i][j] + g[j][k];
    						else state = min(state, f[i][j] + g[j][k]);
    						if((i | (1 << k)) == ((1 << n) - 1)) ans = min(ans, state);
    					}
    	printf("%d
    ", ans);
    	
    	return 0;
    }
  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819334.html
Copyright © 2011-2022 走看看