HDU 2167 Pebbles(状态压缩dp)

来源:互联网 发布:stc51单片机的优点 编辑:程序博客网 时间:2024/06/05 06:43
Problem Description
You're given an unlimited number of pebbles to distribute across an N x N game board (N drawn from [3, 15]), where each square on the board contains some positive point value between 10 and 99, inclusive. A 6 x 6 board might look like this:

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. 

 

Input
Each board is expressed as a series of lines, where each line is a space-delimited series of numbers. A blank line marks the end of each board (including the last one)

 

Output
then your program would print the maximum number of points one can get by optimally distributing pebbles while respecting the two rules, which would be this (each output should be printed on a single line and followed with a newline):

 

Sample Input
71 24 95 56 5485 50 74 94 2892 96 23 71 1023 61 31 30 4664 33 32 95 8978 78 11 55 20 1198 54 81 43 39 9712 15 79 99 58 1013 79 83 65 34 1785 59 61 12 58 9740 63 97 85 66 9033 49 78 79 30 16 34 88 54 39 2680 21 32 71 89 63 39 52 90 14 8949 66 33 19 45 61 31 29 84 98 5836 53 35 33 88 90 19 23 76 23 7677 27 25 42 70 36 35 91 17 79 4333 85 33 59 47 46 63 75 98 96 5575 88 10 57 85 71 34 10 59 84 4529 34 43 46 75 28 47 63 48 16 1962 57 91 85 89 70 80 30 19 38 1461 35 36 20 38 18 89 64 63 88 8345 46 89 53 83 59 48 45 87 98 2115 95 24 35 79 35 55 66 91 95 86 8794 15 84 42 88 83 64 50 22 99 13 3285 12 43 39 41 23 35 97 54 98 18 8584 61 77 96 49 38 75 95 16 71 22 1418 72 97 94 43 18 59 78 33 80 68 5926 94 78 87 78 92 59 83 26 88 91 9134 84 53 98 83 49 60 11 55 17 51 7529 80 14 79 15 18 94 39 69 24 93 4166 64 88 82 21 56 16 41 57 74 51 7949 15 59 21 37 27 78 41 38 82 19 6254 91 47 29 38 67 52 92 81 99 11 2731 62 32 97 42 93 43 79 88 44 54 48
 

Sample Output
57268320962755
 
这个题和1565方格取数差不多,升级版,题目意思就是从中取一些数和最大,每个数周围八个数不能取,把1565代码略作修改即可,还有就是读入数据时要当成字符串读入有点麻烦

不懂位运算什么意思的先去百度一下

题目链接:点击打开链接

代码注释:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define N 1<<16int s[N],dp[16][N],map[16][16],sum,n,m,ans;void solve(){    m=0;    for(int i=0; i<(1<<n); i++)        if((i&(i<<1))==0)//相邻的不取的情况存起来,别忘了外面的括号,我也不是很清楚位运算的优先级...懒得记,反正加上括号绝对不会错            s[m++]=i;    memset(dp,0,sizeof(dp));    for(int i=1; i<=n; i++)        for(int j=0; j<m; j++)        {            sum=0;            for(int k=0; k<n; k++)                if(s[j]&(1<<k))//找到s[j]该种情况中都取了哪些数,这个可以通过&运算来实现                    sum+=map[i][k];            dp[i][j]=sum;            for(int k=0; k<m; k++)            {                if(s[j]&s[k])//上下不满足的,跳                    continue;                if(s[j]&(s[k]>>1))//右上不满足的,跳                    continue;                if(s[j]&(s[k]<<1))//左上不满足的,跳                    continue;                dp[i][j]=max(dp[i][j],dp[i-1][k]+sum);//很简单的状态转移方程,上面的全是暴力,唯一的dp思想就是这            }        }    ans=0;    for(int i=0; i<m; i++)        ans=max(ans,dp[n][i]);//最后一行也有很多状态,找出这些状态中最大的    cout<<ans<<endl;}int main(){    char str[111];//读入数据    while(gets(str))    {        int len=strlen(str);        n=0;        for(int i=0; i<len; i+=3)            map[1][n++]=(str[i]-'0')*10+(str[i+1]-'0');        for(int i=2; i<=n; i++)        {            int nn=0;            gets(str);            for(int j=0; j<len; j+=3)                map[i][nn++]=(str[j]-'0')*10+(str[j+1]-'0');        }        solve();        getchar();    }}




0 0
原创粉丝点击