題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2167
Pebbles
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 837 Accepted Submission(s): 465
The player distributes pebbles across the board so that:
?At most one pebble resides in any given square.
?No two pebbles are placed on adjacent squares. Two squares are considered adjacent if they are horizontal, vertical, or even diagonal neighbors. There's no board wrap, so 44 and 61 of row three aren't neighbors. Neither are 33 and 75 nor 55 and 92.
The goal is to maximize the number of points claimed by your placement of pebbles.
Write a program that reads in a sequence of boards from an input file and prints to stdout the maximum number of points attainable by an optimal pebble placement for each.
題意:給一個N*N的矩陣,每個位置是一個正兩位數,選取若干個點使得數字和最大,條件是 選定 i 點後,i 點周圍8個點(當然不能超出邊界)不能再選。
N>=3 && N<=15 典型狀態壓縮
代碼:
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
using namespace std;
#define N 16
int n;
int map[N][N];
int state[1600],ind;//1597
int dp[N][1600];
void done()
{
memset(state,0,sizeof(state));
ind = 0;
for (int i = 0; i < (1<<n); i++)
{
if((i & (i>>1)) || (i & (i<<1)))continue ;
else state[ind++] = i;
}return ;
}
int cal(int c,int s)
{
int res = 0,i = 1;
while(s){
if(s & 1)
res += map[c][i];
s>>=1;
i++;
}
return res;
}
int solve()
{
int ans = 0;
memset(dp,0,sizeof(dp));
for (int i = 0; i < ind; i++){
dp[1][i] = cal(1,state[i]);
ans = max(ans,dp[1][i]);
}
int nstate,mstate;
for (int x = 2; x <= n; x++)
{
for (int i = 0; i < ind; i++)
{ nstate = state[i];
for (int j = 0; j < ind; j++)
{ mstate = state[j];
if((nstate & mstate)!=0||(nstate & (mstate<<1))!=0 || (nstate & (mstate>>1))!=0)continue;
dp[x][j] = max(dp[x-1][i]+cal(x,state[j]),dp[x][j]);
ans = max(ans,dp[x][j]);
}
}
}
return ans;
}
int main()
{
char tmp[155]={};
while(gets(tmp)!=NULL)
{
n = 0;
memset(map,0,sizeof(map));
int len = strlen(tmp);
if(len == 0)continue;
for (int i = 0,tt=10,j=0; i <= len; i++)
{
if(tmp[i]>='0' && tmp[i]<='9'){
j += (tmp[i]-'0')*tt;
tt = 1;
}else{
map[1][++n] = j;
tt = 10;
//printf("%d ",j);
j = 0;
}
}
for (int i = 2; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d",&map[i][j]);
done();
printf("%d\n",solve());
getchar();
}
return 0;
}