前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HOJ-2662Pieces Assignment(状态压缩,动态规划)

HOJ-2662Pieces Assignment(状态压缩,动态规划)

作者头像
ShenduCC
发布2018-04-25 17:22:13
4750
发布2018-04-25 17:22:13
举报
文章被收录于专栏:算法修养

Pieces Assignment Source : zhouguyue Time limit : 1 sec Memory limit : 64 M Submitted : 415, Accepted : 149 Background 有一个n*m的棋盘(n、m≤80,n*m≤80)要在棋盘上放k(k≤20)个棋子,使得任意两个棋子不相邻(每个棋子最多和周围4个棋子相邻)。求合法的方案总数。 Input 本题有多组测试数据,每组输入包含三个正整数n,m和k。 Output 对于每组输入,输出只有一个正整数,即合法的方案数。 Sample Input 2 2 3 4 4 1 Sample Output 0 16 简单dp题,动态规划就是这样,你要自己去理解,真的要别人告诉你这个原理是什么,是又麻烦,又没有效果的。每个人都是从不会到会,不会看别人博客,但是请一定要独立思考,学习动态规划更是要这样。自己的体会对自己来说总是最有用的 状态转移方程:dp[i][j][p]+=dp[i-1][v][p-t];

代码语言:javascript
复制
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>

using namespace std;
long long int dp[85][1<<10][25];//在第i行,棋子为k个,状态为s的状态数
int n,m,k;
int getsum(int x)
{
        int res=0;
    int i=0;
        while(x)
        {
                if(res&&(x&1))
                        return -1;
                if(res=(x&1))
                        i++;
                x>>=1;
        }
        return i;
}
int main()
{
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
                //根据n,m的大小确定行和列
                if(n<m)
                        swap(n,m);
                memset(dp,0,sizeof(dp));
                dp[0][0][0]=1;
                int end=(1<<m)-1;
                for(int i=1;i<=n;i++)
            {
                    for(int p=0;p<=k;p++)
                    {
                          for(int j=0;j<=end;j++)
                              {
                                          int t=getsum(j);
                                          if(t==-1||t>p)
                                                  continue;
                                          for(int v=0;v<=end;v++)
                                          {
                                                  if(getsum(v)==-1||(v&j))
                                                          continue;
                                                  dp[i][j][p]+=dp[i-1][v][p-t];

                                          }


                              }
                        }

                }
                long long int sum=0;
                for(int i=0;i<=end;i++)
             sum+=dp[n][i][k];
                printf("%lld\n",sum);

        }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-12-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档