• HDU 5291 Candy Distribution


    Candy Distribution

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 544    Accepted Submission(s): 214

     
     

    Problem Description
    WY has n kind of candy, number 1-N, The i-th kind of candy has ai. WY would like to give some of the candy to his teammate Ecry and lasten. To be fair, he hopes that Ecry’s candies are as many as lasten's in the end. How many kinds of methods are there?

    Input
    The first line contains an integer T<=11 which is the number of test cases.
    Then T cases follow. Each case contains two lines. The first line contains one integer n(1<=n<=200). The second line contains n integers ai(1<=ai<=200)


    Output
    For each test case, output a single integer (the number of ways that WY can distribute candies to his teammates, modulo 109+7 ) in a single line.


    Sample Input
    2 1 2 2 1 2


    Sample Output
    2 4
    Hint
    Sample: a total of 4, (1) Ecry and lasten are not assigned to the candy; (2) Ecry and lasten each to a second kind of candy; (3) Ecry points to one of the first kind of candy, lasten points to a second type of candy; (4) Ecry points to a second type of candy, lasten points to one of the first kind of candy.


    Author
    FZUACM


    Source
    2015 Multi-University Training Contest 1

    解题:动态规划+规律优化
     
    1.  $定义dp[i]表示两人之间相差i个糖果的情况数$
    2. 当前有a个第i种糖果,那么我们有[dp[j] = dp[j] imes (a/2 + 1) + dp[j-1] imes((a-1)/2+1)+dp[j+1] imes((a-1)/2+1)+cdots + dp[j-a] imes ((a-a)/2 + 1) + dp[j+a] imes ((a-a)/2 + 1)]
    3. $可以发现算出*dp[0]之后,算*dp[1]  = *dp[0] + dp[1] + dp[3] - dp[0] - dp[-2]$
    4. $此时只要把[j+1,j+1+a]的奇数位置的dp值加起来 - [j-a,j]偶数位置的dp值 + *dp[0] = *dp[1]$
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn = 90000;
     5 const LL mod = 1000000007;
     6 LL dp[maxn],sum[2][maxn];
     7 int bound[maxn],n;
     8 int main(){
     9     int kase;
    10     scanf("%d",&kase);
    11     while(kase--){
    12         scanf("%d",&n);
    13         int S = 0;
    14         for(int i = 1; i <= n; ++i){
    15             scanf("%d",bound + i);
    16             S += bound[i];
    17         }
    18         if(S&1) S |= 1;
    19         memset(dp,0,sizeof dp);
    20         memset(sum,0,sizeof sum);
    21         dp[S] = 1;
    22         for(int i = 1,t = (S<<1); i <= n; ++i){
    23             sum[0][0] = dp[0];
    24             sum[1][0] = 0;
    25             for(int j = 1; j <= t; ++j){
    26                 sum[0][j] = sum[0][j-1];
    27                 sum[1][j] = sum[1][j-1];
    28                 sum[j&1][j] += dp[j];
    29                 sum[j&1][j] %= mod;
    30             }
    31             LL ret = 0;
    32             for(int j = 0; j <= bound[i]; ++j){
    33                 ret += (LL)dp[j]*(((bound[i] - j)>>1) + 1);
    34                 ret %= mod;
    35             }
    36             for(int j = 0,p = (bound[i]&1^1); j <= t; ++j){
    37                 dp[j] = ret;
    38                 int x = max(0,j - bound[i] - 1);
    39                 ret += (sum[p][j + bound[i] + 1] - sum[p][j]);
    40                 p ^= 1;
    41                 ret -= sum[p][j] - sum[p][x];
    42                 ret %= mod;
    43             }
    44         }
    45         printf("%I64d
    ",(dp[S] + mod)%mod);
    46     }
    47     return 0;
    48 }
    View Code

     参考这位大大的博客

    $dp[j-1] imes((a-1)/2+1)$就是表示先取第i种的一个给自己,剩下的两人均分,

    但是,我们不一定要全部分,所以那个1就是表示剩下的不分了,为什么乘以$(a-1)/2$,因为两个人可以都分1,都分2,都分$(a-1)/2$,共$(a-1)/2$种

  • 相关阅读:
    关于连通性问题的Tarjan算法暂结
    【BZOJ 3925】[Zjoi2015]地震后的幻想乡 期望概率dp+状态压缩+图论知识+组合数学
    Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路
    【NOIP模拟赛】Drink 二维链表+模拟
    【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
    【BZOJ 4198】[Noi2015]荷马史诗 哈夫曼编码
    【NOIP模拟赛】chess 建图+spfa统计方案数
    【TMD模拟赛】上低音号 链表
    【TMD模拟赛】黄金拼图 Cao
    【BZOJ 4007】[JLOI2015]战争调度 DP+搜索+状压
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4852569.html
Copyright © 2020-2023  润新知