Pebbles
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 21 Accepted Submission(s) : 16
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.
/// 先轉化map,在計算b[](所有滿足條件的狀態),同時求sum[][](每行每種狀態的總和),在求出dp[0],進而求dp;
#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<list>
#include<set>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
char a[50];
int map[16][16];
int b[1600]; ///存儲所有滿足條件的狀態 約 1597
int sum[16][1600];///存儲每行每種狀態的總和
int dp[16][1600];/// dp[r][k] 表示第 r 行 狀態爲 k 時前 r 行最大總和
int n, cnt;
void scan()
{
memset(map, 0, sizeof(map));
int len = strlen(a);
n = 0;
for (int i = 0; i < len; i += 3)
{
map[0][n++] = (a[i] - '0') * 10 + (a[i + 1] - '0');
}
for (int i = 1; i < n; i++)
{
gets(a);
for (int j = 0, k = 0; j < len; j += 3)
{
map[i][k++] = (a[j] - '0') * 10 + (a[j + 1] - '0');
}
}
gets(a);
}
bool Ok(int x)/// 判斷單獨一行是否滿足條件
{
if (x&(x << 1))return false;
return true;
}
void findstk()/// 求出單獨一行所有的可能狀態,即每行可能的所有狀態
{
memset(b, 0, sizeof(b));
cnt = 0; /// 記錄狀態數
for (int i = 0; i<(1 << n); i++)
{
if (Ok(i))
{
b[cnt++] = i;
}
}
}
void getsum()
{
int x;
memset(sum, 0, sizeof(sum));
for (int i = 0; i<n; i++) /// 每一行
{
for (int j = 0; j<cnt; j++) /// 每種狀態
{
int k = 0;
x=b[j];
while (x>0)
{
if (x&1)
{
sum[i][j] += map[i][k];
}
x >>= 1;
k++;
}
}
}
}
bool Okk(int x,int y) /// 上下行滿足條件
{
if((x&y)||(x&(y<<1))||((x<<1)&y))return true;
return false;
}
int main()
{
while (gets(a))
{
scan();
findstk(); /// 求出所有可能的狀態
getsum(); /// 求出每行每種可能狀態的總和
memset(dp,0,sizeof(dp));
for(int i=0; i<cnt; i++) /// 第一行特殊處理
{
dp[0][i]=sum[0][i];
}
for(int i=1; i<n; i++) /// 處理其他每一行
{
for(int j=0; j<cnt; j++) /// 該行的每種狀態
{
for(int k=0; k<cnt; k++) /// 第一行的每種狀態
{
if(Okk(b[j],b[k])) continue; /// 判斷相鄰行是否滿足條件
if(dp[i][j]<dp[i-1][k]+sum[i][j]) /// 上一行的每種狀態與該行 j 狀態組合 取最大的 組合值 得到該行 j 狀態下的最大值
dp[i][j]=dp[i-1][k]+sum[i][j];
}
}
}
int Max=0;
for(int i=0; i<cnt; i++)
{
if(Max<dp[n-1][i])Max=dp[n-1][i];
}
printf("%d\n",Max);
}
return 0;
}