gaiStateDp[i][j][k] = max{gaiStateDp[i-1][k][p]+c[j]},(枚举p的每种状态) gaiStateDp[i][j][k]表示第i行状态为aiState[j],第i-1行状态为aiState[k]的最大炮兵数,且aiState[j],aiState[k],aiState[p]及地形之间互不冲突.
/*炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8514 Accepted: 2986 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。 现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。 Input 第一行包含两个由空格分割开的正整数,分别表示N和M; 接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。 Output 仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。 Sample Input 5 4 PHPP PPHH PPPP PHPP PHHP Sample Output 6 */ #include <stdio.h> #include "string.h" #define MAX_ROW_NUM 100 #define MAX_STATE_NUM 60 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) typedef struct _POSSIBLE_STATE_ST_ { int iStateNum; int aiState[MAX_STATE_NUM]; int aiState1Num[MAX_STATE_NUM];/*1的个数*/ }POSSIBLE_STATE_ST; int gaiMap[MAX_ROW_NUM]; int gaiStateDp[MAX_ROW_NUM][MAX_STATE_NUM][MAX_STATE_NUM]; POSSIBLE_STATE_ST gstPossibleState; int ArtilleryPositionmain(void) { char acInputBuff[11]; int iM; int iN; int iInvalidState; int iLoopM; int iLoopN; int iStateNum; int iLoop; int iLoopState; int iLoopPreLineState; int iLoopPrePreLineState; int iResult = 0; int iMaxPreNum; int iTempState; memset(gaiMap,0,MAX_ROW_NUM*sizeof(int)); memset(gaiStateDp,0,MAX_STATE_NUM*MAX_ROW_NUM*sizeof(int)); /*input*/ scanf("%d %d",&iN,&iM); for (iLoopN = 0; iLoopN < iN; iLoopN++) { scanf("%s",acInputBuff); for (iLoopM = 0; iLoopM < iM; iLoopM++) { gaiMap[iLoopN] = gaiMap[iLoopN]<<1; gaiMap[iLoopN] |= ('H' == acInputBuff[iLoopM]); } } iStateNum = (1<<iM); /*init possible state*/ gstPossibleState.iStateNum = 0; for (iLoopState = 0; iLoopState < iStateNum; iLoopState++) { iInvalidState = 3;//11B for (iLoop = 0; iLoop < iM-1; iLoop++) { if(iInvalidState == (iInvalidState&iLoopState)) { break; } iInvalidState = iInvalidState<<1; } if (iLoop < iM-1) { continue; } iInvalidState = 5;//101B for (iLoop = 0; iLoop < iM-2; iLoop++) { if(iInvalidState == (iInvalidState&iLoopState)) { break; } iInvalidState = iInvalidState<<1; } if (iLoop < iM-2) { continue; } iTempState = iLoopState; gstPossibleState.aiState1Num[gstPossibleState.iStateNum] = 0; while(iTempState) { iTempState &= (iTempState-1); gstPossibleState.aiState1Num[gstPossibleState.iStateNum]++; } gstPossibleState.aiState[gstPossibleState.iStateNum] = iLoopState; gstPossibleState.iStateNum++; } /*resolve*/ for (iLoopN = 0; iLoopN < iN; iLoopN++) { for (iLoopState = 0; iLoopState < gstPossibleState.iStateNum; iLoopState++) { /*hill*/ if (0 != (gaiMap[iLoopN]&gstPossibleState.aiState[iLoopState])) { continue; } if (0 == iLoopN) { gaiStateDp[0][iLoopState][0] = gstPossibleState.aiState1Num[iLoopState]; } else if (1 == iLoopN) { for (iLoopPreLineState = 0; iLoopPreLineState < gstPossibleState.iStateNum; iLoopPreLineState++) { /*hill*/ if (0 != (gaiMap[0]&gstPossibleState.aiState[iLoopPreLineState])) { continue; } if (0 <= gaiStateDp[0][iLoopPreLineState][0] &&0 == (gstPossibleState.aiState[iLoopPreLineState]&gstPossibleState.aiState[iLoopState])) { gaiStateDp[iLoopN][iLoopState][iLoopPreLineState] = gstPossibleState.aiState1Num[iLoopState]+gaiStateDp[0][iLoopPreLineState][0]; } } } else { for (iLoopPreLineState = 0; iLoopPreLineState < gstPossibleState.iStateNum; iLoopPreLineState++) { /*hill*/ if (0 != (gaiMap[iLoopN-1]&gstPossibleState.aiState[iLoopPreLineState])) { continue; } iMaxPreNum = 0; for (iLoopPrePreLineState = 0; iLoopPrePreLineState < gstPossibleState.iStateNum; iLoopPrePreLineState++) { /*hill*/ if (0 != (gaiMap[iLoopN-2]&gstPossibleState.aiState[iLoopPrePreLineState])) { continue; } if (0 == (gstPossibleState.aiState[iLoopPreLineState]&gstPossibleState.aiState[iLoopState]) &&0 == (gstPossibleState.aiState[iLoopPrePreLineState]&gstPossibleState.aiState[iLoopState]) &&0 == (gstPossibleState.aiState[iLoopPrePreLineState]&gstPossibleState.aiState[iLoopPreLineState])) { iMaxPreNum = MAX(iMaxPreNum,gaiStateDp[iLoopN-1][iLoopPreLineState][iLoopPrePreLineState]); } } gaiStateDp[iLoopN][iLoopState][iLoopPreLineState] = gstPossibleState.aiState1Num[iLoopState]+iMaxPreNum; } } } } for (iLoopState = 0; iLoopState < gstPossibleState.iStateNum; iLoopState++) { for (iLoop = 0; iLoop < gstPossibleState.iStateNum; iLoop++) { iResult = MAX(iResult,gaiStateDp[iN-1][iLoopState][iLoop]); } } printf("%d/n",iResult); return 0; }