HDU4301Divide Chocolate

Posted 蒟蒻LQL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4301Divide Chocolate相关的知识,希望对你有一定的参考价值。

题意

  有一块n*2的巧克力,将它分成k块,问有多少种方法。

分析

  emmm是dp没错了。

  最容易想到的状态定义是f[i][j],意思是前i行,分成j块的方案数。但是发现没法转移。(后面会说一下为什么···)

   我们把状态定义为f[i][j][0]和f[i][j][1]。

   f[i][j][0]:前i行分成j块,且第i行的两小块巧克力是没有连在一起的。

   f[i][j][1]:前i行分成j块,且第i行的两小块巧克力是连在一起的。

   我们来把转移分一下类。

   情况1:从i行到i+1行的时候,巧克力的块数多了两块。这说明,第i+1行的两小块一定是分开的,而且没有和第i行的相连。那么转移只有一种情况f[i][j][0]=f[i-1][j-2][0]+f[i-1][j-2][1]

   情况2:从i行到i+1行的时候,巧克力的块数多了一块。如果第i+1行的两小块是连在一起的一整块,那么一定没有和i行的相连。既f[i][j][1]=f[i-1][j-1][0]+f[i-1][j-1][1]。如果第i+1行的两小块是分开的,那么一定有一块是和i行相连。既f[i][j][0]=f[i-1][j-1][1]*2+f[i-1][j-1][0]*2

   情况3:从i行到i+1行的时候,巧克力的块数没有增加。这就说明第i+1行的一定是和i行相连的。如果第i+1行两小块是分开的,那么第i行一定是分开的。所以f[i][j][0]=f[i-1][j][0]。如果i+1行两小块是和在一起的,那么就要分类讨论。

 思路大概就是这个样子。。。

  至于为什么简单的定义为f[i][j]没法转移,因为,我试过了···他就是没法转移···········

  咳咳不闹,我们来看第三种情况,他的转移是和前一行是分开还是连在一起的有关。所以我们要表示出这个状态。

  下面是代码,我尽量写的可读性强一些了···

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 const int maxn=1000+100;
 8 const int MOD=100000007;
 9 int n,k,T;
10 int f[maxn][2*maxn][3];//0分开,1和起来
11 int main(){
12     scanf("%d",&T);
13     for(int t=1;t<=T;t++){
14         memset(f,0,sizeof(f));
15         scanf("%d%d",&n,&k);
16         f[1][1][1]=f[1][2][0]=1;
17         for(int i=2;i<=n;i++){
18             f[i][2*i][0]=1;f[i][1][1]=1;
19             for(int j=2;j<2*i;j++){
20                 //******第1,2种情况***********
21                 f[i][j][1]=(f[i-1][j-1][1]+f[i-1][j-1][0])%MOD;//1.1
22                 f[i][j][0]=(f[i-1][j-1][1]*2+f[i-1][j-1][0]*2)%MOD;//2.1
23                 f[i][j][0]=(f[i][j][0]+f[i-1][j-2][1]+f[i-1][j-2][0])%MOD;//2.2
24 
25                 //*********第3种情况**************
26                 f[i][j][1]=(f[i][j][1]+f[i-1][j][0]*2+f[i-1][j][1])%MOD;
27                 f[i][j][0]=(f[i][j][0]+f[i-1][j][0])%MOD;
28             }
29         }
30         int ans=(f[n][k][0]+f[n][k][1])%MOD;
31         printf("%d\n",ans);
32     }
33 return 0;
34 }
View Code

 

以上是关于HDU4301Divide Chocolate的主要内容,如果未能解决你的问题,请参考以下文章

HDU4301Divide Chocolate

HDU 5783 Divide the Sequence

HDU - 4112 Break the Chocolate(规律)

HDU - 6616 Divide the Stones

HDU 5783 Divide the Sequence(数列划分)

HDU - 3644:A Chocolate Manufacturer's Problem(模拟退火, 求多边形内最大圆半径)