HDU5079 Square

【题目大意】
给你一个n×n(n≤8)n \times n(n≤8)的棋盘,上面有一些格子必须是黑色,其它可以染黑或者染白,对于一个棋盘,定义它的优美度为它上面最大的连续白色子正方形的边长,对于每个0≤i≤n,问有多少种染色方案使得棋盘的优美度为i?

【解题思路】
比较显然的是这个题可以拆成n+1问来处理,每一问相当于求出优美度为i的方案数,但如果我们直接求恰好为i的方案数是比较困难的。考虑转化一下问题,我们就可以求出优美度至多为i的有多少种,这样答案显然就是求个差了。以下考虑我们现在要求的i为sz。

然后n最大才8,一眼看过去满满的状压味道,于是我们开始考虑状压。

一般的状压都是记这一个位置上有没有,但是这里不一样,这里对于解题有一个关键点——长度。然而长度最大也才8,我们可以考虑用一个数字将它记下。
我们发现,对于每一个格子,影响关于这个格子的最大正方形可以包括他的上方和包括它的右侧(有点乱,意思一下)。我们可以用f[i][sta]f[i][sta]来表示DP到了第i行,该行状态为sta的方案数。 这里的sta显然不止是用01来表示的,我们可以把它看成一个n进制,这个sta的每一位代表ii到i+sz−1i+sz-1中每个格子能往上走的白色格子数的最小值。

这样问题变迎刃而解,因为我们发现它很容易转移。。。。。。
很显然DP方程为f[i][newsta]=∑f[i−1][sta]f[i][newsta]=\sum f[i−1][sta] ,newsta为合法的情况(即去掉超过当前要求的边长的)。
然后乱搞就好了。

【参考代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;const int MAXN=10;
const int MAXM=1e5;
const int mod=1e9+7;
int n,m,T;
int f[MAXN][MAXM];
int cnb[MAXN],pws[MAXN][MAXN],ans[MAXN];//cnb=the state can not be
int flag[MAXN];//in or not
char s[MAXN];inline void get_pows()
{for(int i=2;i<MAXN-1;++i){pws[i][0]=1;for(int j=1;j<MAXN-1;++j)pws[i][j]=pws[i][j-1]*i;}
}inline void _reset()
{   m=1;
//  memset(f,0,sizeof(f));memset(ans,0,sizeof(ans));memset(cnb,0,sizeof(cnb));
}inline void init()
{scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%s",s);for(int j=0;j<n;++j){if(s[j]=='o')m=(m<<1)%mod;elsecnb[i]|=(1<<j);}}
}inline void solve()
{ans[0]=1;ans[1]=(m-1+mod)%mod;for(int sz=2;sz<=n;++sz)//size{int k=n-sz+1,ms=pws[sz][k];
//      printf("ms:%d\n",ms);f[0][0]=1;for(int sta=1;sta<ms;++sta)f[0][sta]=0;for(int i=1;i<=n;++i){for(int sta=0;sta<ms;++sta)f[i][sta]=0;for(int cur=0;cur<(1<<n);++cur){if(cur&cnb[i])continue;
//              printf("%d %d here\n",cur,cnb[i]);memset(flag,0,sizeof(flag));for(int j=0;j<n;++j)//line i,row j{if(cur&(1<<j))continue;for(int q=0;q<k;++q)if(j>=q && j<q+sz)flag[q]=1;}
//              for(int q=0;q<k;++q)
//                  printf("%d ",flag[q]);
//              printf("\n");for(int sta=0;sta<ms;++sta){if(!f[i-1][sta])continue;int nsta=0;
//                  printf("%d\n",i);
//                  printf("here\n");for(int j=0;j<k;++j){int t=sta/pws[sz][j]%sz;//sz jingzhi,the jth num
//                      printf("t:%d\n",t);if(flag[j])t=0;elseif(t!=sz-1)++t;else{nsta=-1;break;}nsta+=t*pws[sz][j];
//                      printf("new:%d\n",nsta);}if(nsta==-1)continue;f[i][nsta]=(f[i][nsta]+f[i-1][sta])%mod;}}}
//      printf("%d:\n",sz);
//      for(int i=0;i<ms;++i)
//          printf("%d\n",f[sz][i]);
//      printf("\n\n");for(int sta=0;sta<ms;++sta)ans[sz]=(ans[sz]+f[n][sta])%mod;ans[sz]=(m-ans[sz]+mod)%mod;ans[sz-1]=(ans[sz-1]-ans[sz]+mod)%mod;}for(int sz=0;sz<=n;++sz)printf("%d\n",ans[sz]);
}int main()
{freopen("HDU5079.in","r",stdin);freopen("HDU5079.out","w",stdout);get_pows();scanf("%d",&T);while(T--){_reset();init();solve();}return 0;
}

LGP2051 [AHOI2009]中国象棋

【题目描述】

这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!

【输入输出格式】

【输入格式】
一行包含两个整数N,M,之间由一个空格隔开。

【输出格式】
总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。

【输入样例】
1 3

【输出样例】
7

【数据范围】
100%的数据中N和M均不超过100
50%的数据中N和M至少有一个数不超过8
30%的数据中N和M均不超过6

【题目分析】
说实话,这题在LG上是紫色,但个人认为并没有到这个程度,因为太好想了。。。
我们发现,若我们对行进行dp,则做到当前行的方案数,只和之前有多少列放了多少个棋子有关,和具体怎么放实际上是无关的。显然我们可以考虑:
令f[i][j][k]f[i][j][k]为做到第i行,一共有j列放了1个棋子,有k列放了2个棋子的方案数。
然后胡乱转移就行了。

【参考代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;typedef long long LL;
const int mod=9999973;
const int MAXN=105;
int ans,n,m;
LL f[MAXN][MAXN][MAXN];//f[i][j][k]=now row i,have j rows 1chess,have k rows 2chessint main()
{freopen("LGP2051.in","r",stdin);freopen("LGP2051.out","w",stdout);scanf("%d%d",&n,&m);f[1][0][0]=1;f[1][1][0]=m;f[1][2][0]=m*(m-1)/2;for(int i=2;i<=n;++i){for(int j=0;j<=m;++j){for(int k=0;k<=m;++k){LL tot=0;tot+=f[i-1][j][k];//nothingtot+=f[i-1][j+1][k-1]*(j+1);//put 1 in 1tot+=f[i-1][j-1][k]*(m-j-k+1);//put 1 in 0tot+=f[i-1][j-2][k]*(m-j-k+2)*(m-j-k+1)/2;//put 2 in 0tot+=f[i-1][j+2][k-2]*(j+2)*(j+1)/2;//put 2 in 1tot+=f[i-1][j][k-1]*j*(m-j-k+1);//put 1 in 0,1 in 1f[i][j][k]=tot%mod;}}}for(int i=0;i<=m;++i)for(int j=0;j<=m;++j)ans=(ans+f[n][i][j])%mod;printf("%d\n",ans);return 0;
}

【dp水题】HDU5079+LGP2051相关推荐

  1. 寒假每日一题题解(1.29)摘花生(DP水题)

    摘花生 Hello Kitty想摘点花生送给她喜欢的米老鼠. 她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来. 地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过 ...

  2. 洛谷P1352 没有上司的舞会(树形DP水题)

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

  3. 合并石子 区间dp水题

    合并石子 链接: nyoj 737 描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N- ...

  4. 学校作业-Usaco DP水题

    好吧,因为USACO挂掉了,所以我写的所有代码都不保证正确性[好的,这么简单的题,再不写对,你就可以滚粗了! 第一题是USACO 2.2.2 ★Subset Sums 集合  对于从 1 到 N 的连 ...

  5. POJ1887 DP水题儿

    http://poj.org/problem?id=1887 题目很基础,就是求 最长减子数列 dp[i]=max{  max{  dp[j]+1 (arr[i]<arr[j]  ;  1< ...

  6. 郊区春游(状压DP水题)+ 记录路径

    题目链接: https://ac.nowcoder.com/acm/problem/16122 题目大意: 中文 具体思路: 首先对全图跑一遍floyed,然后dp[i][j]表示第i个状态在j点停下 ...

  7. UVA 1025 A Spy in the Metro DP水题

    简单DAG,每个状态有三种决策,原地傻等,上往左开的车,上往右开的车. #include <cstdio> #include <cstring> #include <io ...

  8. [Offer收割]编程练习赛2 hihocoder 1272 买零食 (DFS 或 dp 水题)

    时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho很喜欢在课间去小卖部买零食.然而不幸的是,这个学期他又有在一教的课,而一教的小卖部姐姐以冷若冰霜著称.第一次去一教小卖 ...

  9. 关于一道你们眼中的水题 Windy数 的乱写(数位dp)

    啊一道水题有什么好说的 上课听不懂,下课泪两行. 有的人什么套路都会,我.. 只能可怜巴巴的抄代码,然后自己总结,顺(zhu)便(yao)颓博客 1.递推dp的思路做到一半死了,怎么也想不出来如何处理 ...

最新文章

  1. 基本环境安装: Centos7+Java+Hadoop+Spark+HBase+ES+Azkaban
  2. html如何与php,html页面怎么跟php文件连接
  3. python字典的键可以是列表吗_如何返回字典键作为Python中的列表?
  4. JPA、JTA与JMS
  5. android drawable 对象,Android Drawable开发简介
  6. 随想录(MFC开发有感)
  7. Macos 12 打不开微信解决方案
  8. DevExpress学习03——label控件的背景色问题
  9. 亲密关系-【沟通提示】-如何把学习到的东西用到生活中
  10. 禁用生成8.3字符长文件名解决单目录存储大量文件写入性能下降问题
  11. ValueError: expected sequence of length 791 at dim 1 (got 185)
  12. 学技术的不能自废武功
  13. 用户交互系统BBS功能展示(手机端)
  14. mate7 android升级包下载,华为mate7 刷机包
  15. Silverlight XAP文件运行器
  16. Numpy中take的用法
  17. python transforms_pytorch中的transforms模块实例详解
  18. 《三国演义》统帅对比
  19. Anaconda3安装教程及配置(全)
  20. UE4入门(从Unity3D转学UE4)

热门文章

  1. vue项目部署后刷新网页报404错误解决
  2. Arduino Uno 开发简介
  3. 面试官:连漏桶算法和令牌桶算法都不知道吗?回去多看看书吧
  4. Linux查看tomcat服务进程号,Linux下启动停止查看杀死Tomcat进程
  5. 看不懂CAD建筑图纸怎么办?有什么CAD快速看图或识图的技巧吗?
  6. 7. Jackson用树模型处理JSON是必备技能,不信你看
  7. 小红书素人KOC素人笔记种草传播如何做到专业不踩坑?
  8. matlab工作节拍优化,装配生产线任务平衡优化遗传算法通用MATLAB源码
  9. 计算机开启远程服务与修改端口号教程
  10. MYSQL - DML