bnuoj 12976 Collecting Gold 狀壓dp

http://www.bnuoj.com/problem_show.php?pid=12976

參考:
https://blog.csdn.net/u013008291/article/details/47972041

狀態轉移方程:

dp[s|1<<j][j] = min(dp[s|1<<j][j],dp[s][i]+ dis(i,j) );

code:


#include <iostream>
#include <stdio.h>
#include <string>
#include <typeinfo>
#include <stack>
#include <vector>
#include <sstream>
#include <string.h>
#include <map>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
typedef long long LL;

char G[20][20];
int dp[1<<16][16];

struct point{
    int x,y;
}p[16];

int goldcnt = 0;

int dis(int i,int j){
    point p1 = p[i];
    point p2 = p[j];
    return max(abs(p1.x-p2.x),abs(p1.y-p2.y));
}
int cal(){
    memset(dp,0x3f,sizeof(dp));
    dp[0][goldcnt-1] = 0;
    for(int s = 0 ;s < (1<<goldcnt);s++){
        for(int i = 0;i < goldcnt ;i++){
            for(int  j = 0;j< goldcnt ;j++){
                if(!(s&(1<<j) )){
                    dp[s|1<<j][j] = min(dp[s|1<<j][j],dp[s][i]+ dis(i,j) );
                }
            }
        }
    }
    return dp[ (1<<goldcnt)-1 ][goldcnt-1];
}
int main()
{
    int T;
    scanf("%d",&T);
    int m,n;
    for(int ca = 1;ca<=T;ca++){
        int ret = 0;
        int sx,sy;
        goldcnt = 0;
        scanf("%d%d",&m,&n);
        for(int i=0;i<m;i++){
            scanf("%s",G[i]);
            for(int j=0;j<n;j++){
                if(G[i][j]=='g'){
                    p[goldcnt].x = i;
                    p[goldcnt].y = j;
                    goldcnt++;
                }else if(G[i][j]=='x'){
                    sx = i;
                    sy = j;
                }
            }
        }
        p[goldcnt].x = sx;
        p[goldcnt].y = sy;
        goldcnt ++;
        cout<<"Case "<<ca<<": "<<cal()<<endl;
    }

    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章