关闭

【NOIP2013模拟】粉刷匠

标签: NOIP2013模拟粉刷匠DP组合数学
646人阅读 评论(0) 收藏 举报
分类:

Description

给出n个球,其中有C1个球是颜色1的,有C2个球是颜色2的,有C3个球是颜色3的……
有Ck个球是颜色k的。求相邻两个球颜色不同的排列方案。
k<=15,ci<=6,数据组数<=2000

Solution

这种题一般很难有直接的通式,可以考虑Dp。
设Fi,j表示,前i中颜色已经放完了,其中产生了j个不合法的空的方案数。(这里的空指的是每两个球中间的位置,包括开头结尾,不合法即指两边的球的颜色相同)
我们再枚举一个p和q,表示这种颜色要放到p个合法空和q个不合法空。
那么新的j呢?
因为我们放入了q个不合法空,所以j会减去q,然后,总共有C[i+1]个球,在p+q个空中各放了一个后,剩下的无论怎么放都会产生一个不合法空,所以加上C[i+1]-p-q
即:F[i,j]->F[i+1,j+C[i+1]-p-q]
然后如何转移,首先,我们要把C[i+1]个球放到p+q个空中,每个空都必须要放,所以有Cp+q1C[i+1]1种方法放,然后,在现有的j个空中选q个,乘上Cqj,设总共有sum个空,再乘上Cpsumj
然后这道题就解决了。
Ps:由于比赛时特别方,我疯狂滴优化常数,打得非常的渣渣。

Code

#include<cstdio>
#include<cstring>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define mo 1000000007
#define N 105
using namespace std;
typedef long long ll;
int n,ty,x,c[N][N],f[20][N];
int min(int x,int y) {if (x<y) return x;else return y;}
int get() {
    char ch;
    while (!isdigit(ch=getchar()));int o=ch-48;
    while (isdigit(ch=getchar())) o=o*10+ch-48;
    return o;
}
int main() {
    c[0][0]=1;
    fo(i,1,95) {
        c[i][0]=1;
        fo(j,1,i) {
            c[i][j]=c[i-1][j]+c[i-1][j-1];
            c[i][j]-=c[i][j]/mo*mo;
        }
    } 
    for(ty=get();ty;ty--) {
        n=get();f[0][0]=1;int sum=0;
        fo(i,1,n) {
            x=get();fo(j,0,sum+x+1) f[i][j]=0;
            fo(j,0,sum) 
                fo(k,0,min(j,x))
                    fo(l,0,min(x-k,sum+1-j)) {
                        if (!(k+l)) continue;
                        int ans=f[i-1][j];int y=j+x-2*k-l;
                        ans=(ll)ans*c[x-1][k+l-1]-(ll)ans*c[x-1][k+l-1]/mo*mo;
                        ans=(ll)ans*c[j][k]-(ll)ans*c[j][k]/mo*mo;
                        ans=(ll)ans*c[sum+1-j][l]-(ll)ans*c[sum+1-j][l]/mo*mo;
                        f[i][y]+=ans;f[i][y]-=f[i][y]/mo*mo;
                    }sum+=x;
        }
        printf("%d\n",f[n][0]);
    }
}
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

【NOIP2013模拟】粉刷匠 题解&代码

原题Description赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= =现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍。赫克托有K桶颜色各不相同的油漆,第i...
  • liyizhixl
  • liyizhixl
  • 2016-05-30 20:22
  • 9664

【NOIP2013模拟联考7】数列

Description给出一个序列,每个数由一个二元组(a,b)表示,有4中操作 1:把a值在l~r范围内的数乘上x再加上y 2:把b值在l~r范围内的数乘上x再加上y 3:询问a值在l~r范围...
  • alan_cty
  • alan_cty
  • 2016-06-25 16:23
  • 504

我是一个粉刷匠

原文地址:www.sj11wang.com
  • sj11wang
  • sj11wang
  • 2017-08-04 19:41
  • 39

粉刷匠&集体照

题目大意有m个种类的球,第i个种类有r[i]个球,把球排成一行是使得相邻两个球种类不同,问方案数。DP我们可以一个种类一个种类的放球。 两个球中间以及最前最后都有“空”。 定义非法空指该空两端是同...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016-05-28 14:43
  • 309

2014.7.8模拟赛【笨笨当粉刷匠】

笨笨太好玩了,农田荒芜了,彩奖用光了,笨笨只好到处找工作,笨笨找到了一份粉刷匠的工作。笨笨有n条木板需要被粉刷。每条木板被分成m个格子,每个格子要被刷成红色或蓝色。笨笨每次粉刷,只能选择一条木板上一段...
  • zhb1997
  • zhb1997
  • 2014-07-08 22:47
  • 485

bzoj 1296 【粉刷匠】

题目: windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被...
  • mars_ch
  • mars_ch
  • 2016-10-11 20:48
  • 71

【NOIP2013模拟联考6】选课(select)

Description求1~n的排列中,i不放在i和i+1且n不放在1的方案数。 n<=10^5Solution容斥原理乱搞。 表示蒟蒻只能看题解了。。。 我们设W(k)表示至少有k个位置不合法...
  • alan_cty
  • alan_cty
  • 2016-06-27 20:30
  • 829

SCOI2009——粉刷匠(动态规划)

1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 528  Solved: 292 [Submit...
  • jianing1996
  • jianing1996
  • 2013-05-20 15:26
  • 811

【bzoj1296】【scoi2009】【粉刷匠】【dp】

Description windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。...
  • sunshinezff
  • sunshinezff
  • 2015-09-17 17:11
  • 763

【BZOJ1296】[SCOI2009]粉刷匠(动态规划)

题目:BZOJ1296 分析: 这题一看就是动态规划。 可以看出,如果每个木条粉刷的次数是固定的,那么这些木条是互不干扰的,因此对于每个木条可以通过dp来求出把T次中的j次分配给这个木条时可以获得的最...
  • hqddm1253679098
  • hqddm1253679098
  • 2017-12-10 21:18
  • 45
    个人资料
    • 访问:164899次
    • 积分:5303
    • 等级:
    • 排名:第6036名
    • 原创:360篇
    • 转载:4篇
    • 译文:0篇
    • 评论:79条
    博客公告
    我觉得我已经是一碗废蘑菇汤了……
    博客专栏
    文章分类
    最新评论