3 4 4 2 2 100 200 **** *@A* *B<* **** 4 4 1 2 100 200 **** *@A* *B<* **** 12 5 13 2 100 200 ************ *B.........* *.********.* *@...A....<* ************
Case 1: The best score is 200. Case 2: Impossible Case 3: The best score is 300.
想法:因为题目数据规模较小,故转化为TSP再求解
代码:
#include <stdio.h> #include <queue> #include <iostream> using namespace std; const int MAX_VALUE = 50; int W, H, L, M; int iCaseCount; int Value[11]; //value of jewels char Map[MAX_VALUE + 1][MAX_VALUE + 1]; //map data int GraphNodeCount; int GraphEdge[12][12]; //graph int NodeEnCode[MAX_VALUE * MAX_VALUE]; int NodeDeCode[12]; int Dist[MAX_VALUE][MAX_VALUE]; const int INF = 0x00FFFFFF; static int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; int iMaxValue; int Bit[10]; int Dp[11][1024]; int FetchPathLength(int iCurNode, int iSet); void Handle(); void InputData(); void BuildGraph(); void BFS(int Row, int Col); bool Valid(int Row, int Col);//valid block int GetBit(int iSet); int main(){ cin >> iCaseCount; for(int i= 0; i< iCaseCount; ++i) { Handle(); } } void Handle(){ bool flag = true; static int iCase = 1; memset(GraphEdge, 0, sizeof(GraphEdge)); memset(Dist, 0, sizeof(Dist)); memset(Dp, 0, sizeof(Dp)); iMaxValue = 0; InputData(); BuildGraph(); if(GraphEdge[M][M + 1] == INF || GraphEdge[M][M + 1] > L) { flag = false; goto Result; } int iCurMaxValue; int iEmpty = 0, iFull = (1 << M) - 1; for(int iSet = iEmpty; iSet <= iFull; ++iSet) { iCurMaxValue = GetBit(iSet); if(iCurMaxValue <= iMaxValue) continue; memset(Dp, 0, sizeof(Dp)); if(FetchPathLength(M, iSet) <= L) iMaxValue = iCurMaxValue; } Result: cout << "Case " << iCase << ':' << endl; if(flag == 1) cout << "The best score is " << iMaxValue << '.' << endl; else cout << "Impossible" << endl; if(iCase < iCaseCount) cout << endl; iCase++; } void InputData(){ GraphNodeCount = 0; cin >> W >> H >> L >> M; for(int i = 0; i < M; ++i) { cin >> Value[i]; } for(int i = 0; i < H; ++i) { cin >> Map[i]; for(int j = 0; j < W; ++j) { if(Map[i][j] >= 'A' && Map[i][j] <= 'J') {//a jewel NodeDeCode[Map[i][j] - 'A'] = 50 * i + j; NodeEnCode[50 * i + j] = Map[i][j] - 'A'; ++GraphNodeCount; } else if(Map[i][j] == '@') {//start NodeDeCode[M] = 50 * i + j; NodeEnCode[50 * i + j] = M; } else if(Map[i][j] == '<') {//target NodeDeCode[M + 1] = 50 * i + j; NodeEnCode[50 * i + j] = M + 1; } } } } void BuildGraph(){ for(int i = 0; i < M + 2; ++i) { fill(GraphEdge[i], GraphEdge[i] + M + 2, INF); } int Row, Col, NextRow, NextCol; for(int i = 0; i < M + 2; ++i) { Row = NodeDeCode[i] / 50, Col = NodeDeCode[i] % 50; BFS(Row, Col); for(int j = 0; j < M + 2; ++j) { NextRow = NodeDeCode[j] / 50, NextCol = NodeDeCode[j] % 50; if(Dist[NextRow][NextCol] != INF) { GraphEdge[i][j] = GraphEdge[j][i] = Dist[NextRow][NextCol]; } } } } void BFS(int Row, int Col){ for(int i = 0; i < H; ++i) { fill(Dist[i], Dist[i] + W, INF); } Dist[Row][Col] = 0; deque<pair<int, int> > q; q.push_front(make_pair(Row, Col)); pair<int, int> CurNode, NextNode; bool Visit[50][50]; memset(Visit, 0, sizeof(Visit)); Visit[Row][Col] = true; while(!q.empty()) { CurNode = q.back(), q.pop_back(); for(int i = 0; i < 4; ++i) { NextNode = CurNode; NextNode.first += dir[i][0], NextNode.second += dir[i][1]; if(Valid(NextNode.first, NextNode.second) && !Visit[NextNode.first][NextNode.second]) { Dist[NextNode.first][NextNode.second] = Dist[CurNode.first][CurNode.second] + 1; q.push_front(NextNode); Visit[NextNode.first][NextNode.second] = true; } } } } bool Valid(int Row, int Col){ return Row >= 0 && Row < H && Col >= 0 && Col < W && Map[Row][Col] != '*'; } int GetBit(int iSet){ int iValue = 0; for(int i = 0; i < M; ++i) { Bit[i] = iSet % 2; if(Bit[i]) iValue += Value[i]; iSet >>= 1; } return iValue; } int FetchPathLength(int iCurNode, int iSet){ if(Dp[iCurNode][iSet]) { return Dp[iCurNode][iSet]; } else if(iSet == 0) {//no subset Dp[iCurNode][iSet] = GraphEdge[iCurNode][M + 1]; return Dp[iCurNode][iSet]; } int bit[11] = {0}, iTmpSet = iSet; Dp[iCurNode][iSet] = INF; for(int i = 0; i < M; ++i) { bit[i] = iTmpSet % 2, iTmpSet >>= 1; } for(int i = 0; i < M; ++i) { if(bit[i]) { Dp[iCurNode][iSet] = min(Dp[iCurNode][iSet], GraphEdge[iCurNode][i] + FetchPathLength(i, iSet ^ (1 << i))); } } return Dp[iCurNode][iSet]; }
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
15325029 | 2015-10-31 22:27:14 | Accepted | 1044 | 62MS | 1872K | 4996 B | C++ | BossJue |