zoukankan      html  css  js  c++  java
  • bzoj 4583 购物

    4583: 购物

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 32  Solved: 16
    [Submit][Status][Discuss]

    Description

    商店出售3种颜色的球,分别为红、绿、蓝。城市里有n个商店,第i个商店在第First_i天开始营业,连续营业Red_
    i+Green_i+Blue_i天,每个商店每天只能出售一种颜色的球。每天最多有两个商店同时营业。如果同一天内有两个
    商店同时营业,那么这两个商店必须出售相同颜色的球。求不同的出售方案数(对1,000,000,007取模)。两种方
    案不同,当且仅当某一天某一个商店出售的球的颜色不同。
     

    Input

    第一行只包含一个整数n,表示商店的个数。
    接下来一行有n个数,第i个数表示First_i。
    接下来一行有n个数,第i个数表示Red_i。
    接下来一行有n个数,第i个数表示Green_i。
    接下来一行有n个数,第i个数表示Blue_i。
    1≤n≤50
    1≤First_i≤500
    0≤Red_i, Green_i, Blue_i≤100
    0<Red_i + Green_i + Blue_i
    First_i + Red_i + Green_i + Blue_i - 1≤500
    保证每天最多有两个商店同时营业。
     

    Output

    输出仅包含一个数,表示对1,000,000,007取模后的方案数。
     
     
    首先想到dp,f[i][j][k]表示当前第i天,当前的商店已经卖了j个红气球,k个绿气球,这样用蓝气球的个数也是可以知道的。要是有两个区间包含的情况,则可以直接乘组合数转移。相当于被包含的区间强行放满。前后两个区间有交叉同理,因为由当前的状态可以知道接下来交叉的区间要卖红、绿、蓝气球各多少个,所以就可以直接乘组合数转移。其他情况直接转移。
     
    感觉代码写的很丑,注意排序前后的顺序不同,不要搞混
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define mod 1000000007
      7 #define maxn 120
      8 
      9 typedef long long ll;
     10 struct node{
     11     int l,r,rd,bl,gr;
     12     bool operator < (node a)const{
     13         return l < a.l;
     14     }
     15 }dt[maxn],dt2[maxn];
     16 ll f[maxn * 10][maxn][maxn],fac[520],inv[520],ans;
     17 int n,m,tag[maxn],tot,cov[maxn * 10],bl[maxn * 10];
     18 int R[maxn],B[maxn],G[maxn],mxR,mxB,mxG,R2[maxn],B2[maxn],G2[maxn];
     19 
     20 inline ll power(ll x,int y){
     21     ll res = 1;
     22     while ( y ){
     23         if ( y & 1 ) res = res * x % mod;
     24         y >>= 1;
     25         x = x * x % mod;
     26     }
     27     return res % mod;
     28 }
     29 void init(){
     30     fac[0] = inv[0] = 1;
     31     for (int i = 1 ; i <= 500 ; i++) fac[i] = (ll)i * fac[i - 1] % mod , inv[i] = power(fac[i],mod - 2);
     32     for (int i = 1 ; i <= n ; i++) dt[i].rd = R[i] , dt[i].gr = G[i] , dt[i].bl = B[i];
     33     sort(dt + 1,dt + n + 1);
     34     for (int i = 1 ; i <= n ; i++) R[i] = dt[i].rd  , G[i] = dt[i].gr , B[i] = dt[i].bl;
     35     for (int i = 1 ; i <= n ; i++){
     36         for (int j = 1 ; j <= n ; j++){
     37             if ( j == i ) continue;
     38             if ( dt[i].l <= dt[j].l && dt[i].r >= dt[j].r ) tag[j] = 1;
     39         }
     40     }
     41     for (int i = 1 ; i <= m ; i++){
     42         for (int j = 1 ; j <= n ; j++){
     43             if ( tag[j] ) continue;
     44             if ( dt[j].l <= i && dt[j].r >= i ) cov[i]++;
     45             if ( dt[j].l > i ) break;
     46         }
     47     }
     48     for (int i = 1 ; i <= n ; i++){
     49         if ( tag[i] ){
     50             bl[dt[i].l] = i;
     51         }
     52     }
     53 }
     54 void Dodp(){
     55     int cur = 1;
     56     while ( tag[cur] ) cur++;
     57     f[0][0][0] = 1;    
     58     for (int i = 1 ; i <= m ; i++){
     59         if ( !cov[i] ){
     60             if ( !cov[i - 1] ) f[i][0][0] = f[i - 1][0][0];
     61             else{
     62                 for (int j = 0 ; j <= R[cur] ; j++){
     63                     for (int k = 0 ; k <= G[cur] ; k++){
     64                         f[i][0][0] = (f[i][0][0] + f[i - 1][j][k]) % mod;
     65                     }
     66                 }
     67             }
     68             continue;
     69         }
     70         if ( i > dt[cur].r ){
     71             for (int j = 0 ; j <= R[cur] ; j++){
     72                 for (int k = 0 ; k <= G[cur] ; k++){
     73                     f[i][0][0] = (f[i][0][0] + f[i - 1][j][k]) % mod;
     74                 }
     75             }
     76             f[i - 1][0][0] = f[i][0][0] , f[i][0][0] = 0;
     77             cur++;
     78             while ( tag[cur] ) cur++;
     79         }
     80         if ( cov[i] == 2 ){
     81             int jump = dt[cur].r;
     82             for (int j = 0 ; j <= R[cur] ; j++){
     83                 for (int k = 0 ; k <= G[cur] && j + k <= i - dt[cur].l ; k++){
     84                     int r = R[cur] - j , g = G[cur] - k , b = B[cur] - (i - dt[cur].l - j - k);
     85                     if ( b < 0 || r + g + b < jump - i + 1 ) continue;
     86                     f[jump][r][g] = (f[jump][r][g] + fac[jump - i + 1] * inv[r] % mod * inv[g] % mod * inv[b] % mod * f[i - 1][j][k]) % mod;
     87                 }
     88             }
     89             cur++ , i = jump;
     90             while ( tag[cur] ) cur++;
     91         }
     92         else{
     93             if ( bl[i] ){
     94                 int jump = dt[bl[i]].r;
     95                 for (int j = 0 ; j <= R[cur] ; j++){
     96                     for (int k = 0 ; k <= G[cur] && j + k <= i - dt[cur].l ; k++){
     97                         int r = R[bl[i]] + j , g = G[bl[i]] + k , b = B[bl[i]] + (i - dt[cur].l - j - k);
     98                         if ( r > R[cur] || g > G[cur] || b > B[cur] ) continue;
     99                         f[jump][r][g] = (f[jump][r][g] + fac[jump - i + 1] * inv[R[bl[i]]] % mod * inv[G[bl[i]]] % mod * inv[B[bl[i]]] % mod * f[i - 1][j][k]) % mod;
    100                     }
    101                 }
    102                 i = jump;
    103                 continue;
    104             }
    105             for (int j = 0 ; j <= R[cur] ; j++){
    106                 for (int k = 0 ; k <= G[cur] && j + k <= i - dt[cur].l + 1 ; k++){
    107                     int b = i - dt[cur].l + 1 - j - k;
    108                     if ( b > B[cur] ) continue;
    109                     if ( j > 0 ) f[i][j][k] = (f[i][j][k] + f[i - 1][j - 1][k]) % mod;
    110                     if ( k > 0 ) f[i][j][k] = (f[i][j][k] + f[i - 1][j][k - 1]) % mod;
    111                     if ( b > 0 ) f[i][j][k] = (f[i][j][k] + f[i - 1][j][k]) % mod;
    112                 }
    113             }
    114         }    
    115     }
    116 }
    117 int main(){
    118 //    freopen("input.txt","r",stdin);
    119     scanf("%d",&n);
    120     for (int i = 1 ; i <= n ; i++) scanf("%d",&dt[i].l);
    121     for (int i = 1 ; i <= n ; i++) scanf("%d",&R[i]) , mxR = max(mxR,R[i]);
    122     for (int i = 1 ; i <= n ; i++) scanf("%d",&G[i]) , mxG = max(mxG,G[i]);
    123     for (int i = 1 ; i <= n ; i++) scanf("%d",&B[i]) , mxB = max(mxB,B[i]);
    124     for (int i = 1 ; i <= n ; i++) dt[i].r = dt[i].l + R[i] + G[i] + B[i] - 1 , m = max(m,dt[i].r);
    125     init();
    126     Dodp();
    127     for (int j = 0 ; j <= 100 ; j++) 
    128         for (int k = 0 ; k <= 100 ; k++)
    129             ans = (ans + f[m][j][k]) % mod;
    130     printf("%lld
    ",ans);
    131     return 0;
    132 }
  • 相关阅读:
    POJ3320 Jessica's Reading Problem
    POJ3320 Jessica's Reading Problem
    CodeForces 813B The Golden Age
    CodeForces 813B The Golden Age
    An impassioned circulation of affection CodeForces
    An impassioned circulation of affection CodeForces
    Codeforces Round #444 (Div. 2) B. Cubes for Masha
    2013=7=21 进制转换
    2013=7=15
    2013=7=14
  • 原文地址:https://www.cnblogs.com/zqq123/p/5501976.html
Copyright © 2011-2022 走看看