zoukankan      html  css  js  c++  java
  • hdu 5291 dp+优化 ****

    多校实在高能

    题解链接

    题意:有n中糖果,每种糖果有ai个。分给A,B两个人。两人的糖果要一样多,可以都是0,1......m个。同一种糖果没有区别。

    问有几种分法。


    定义dp[i]表示两人之间相差i个糖果的情况数。对每种糖果进行处理  *dp[i]表示新计算得到的dp值

    当当前有ai个i种糖果时。处理*dp[j]

    *dp[j] = dp[j]*(ai/2+1) + dp[j-1]*((ai-1)/2+1) + dp[j+1]*((ai-1)/2+1) ............+dp[j-ai]*((ai-ai)/2+1) + dp[j+ai]*((ai-ai)/2+1)

    表示dp[j-k]*((ai-k)/2+1)表示原来A,B相差j-k个糖果,但是通过分第i种糖果,先给A分了k个糖果,让后剩下的糖果再平等 地分给A,B。那么分完之后就相差j个糖果了。由于提前给A,k个糖果,那么剩下ai-k个糖果,平分剩下糖果的情况有(ai-k)/2+1种。+1是两 个人人都分0个。

    假设ai = 2 j = 0, 那么dp[0] = 

    dp:      dp[-2]   dp[-1]  dp[0] dp[1] dp[2]

    系数:1             1          2        1         1


    算出*dp[0]之后,算*dp[1]  = *dp[0] + dp[1] + dp[3] - dp[0] - dp[-2]

    可以发现此时只要把[j+1,j+1+ai]的奇数位置的dp值加起来 - [j-ai,j]偶数位置的dp值 + *dp[0] = *dp[1]

    转移变成O(1)的了。



    假设ai = 3 j = 0, 那么dp[0] = 

    dp:     dp[-3]  dp[-2]   dp[-1]  dp[0] dp[1] dp[2]   dp[3]

    系数:1             1          2        2         2         1         1

    同ai = 2相反。找规律即可。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 using namespace std;
     6 #define ll long long
     7 int dp[90000],sum[2][90000];
     8 int mod = 1000000007;
     9 int modx = -mod;
    10 int num[300];
    11 int main(){
    12     int t,n;
    13     scanf("%d",&t);
    14     while(t--){
    15         scanf("%d",&n);
    16         int total = 0;
    17         for(int i = 1; i <= n; i++){
    18             scanf("%d",&num[i]);
    19             total += num[i];
    20         }
    21         if(total & 1) total++;
    22         memset(dp,0,sizeof(dp));
    23         memset(sum,0,sizeof(sum));
    24         dp[total] = 1;
    25         int tt = total*2;
    26         for(int i = 1; i <= n; i++)
    27         {
    28             sum[0][0] = dp[0];
    29             sum[1][0] = 0;
    30             for(int j = 1;j <= tt; j++)
    31             {
    32                 sum[0][j] = sum[0][j-1];
    33                 sum[1][j] = sum[1][j-1];
    34                 sum[j&1][j] += dp[j];
    35                 sum[j&1][j] %= modx;
    36             }
    37             ll ans = 0;
    38             for(int j = 0;j <= num[i]; j++){
    39                 ans += (ll)dp[j]*((num[i]-j)/2+1);
    40                 ans %= mod;
    41             }
    42             int p = (num[i]&1)^1;
    43             int res = ans;
    44             for(int j = 0;j <= tt; j++)
    45             {
    46                 dp[j] = res;
    47                 int u = j-num[i]-1;
    48                 u = max(u,0);
    49                 res += (sum[p][j+1+num[i]] - sum[p][j])%mod;
    50                 res %= mod;
    51                 p ^= 1;
    52                 res -= (sum[p][j] - sum[p][u])%mod;
    53                 res %= mod;
    54             }
    55         }
    56         int res = dp[total];
    57         res %= mod;
    58         res = (res+mod)%mod;
    59         cout<<res<<endl;
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    Alibaba 阿里组件 nacos注册中心 gateway网关 flowable流程引擎 vue.js前后分离 spring cloud微服务
    Java JDBC 连接 MySQL8 数据库
    Java设计模式【命令模式】
    Spring Boot内嵌tomcat关于getServletContext().getRealPath获取得到临时路径的问题
    Java代理模式学习 (Proxy模式)
    Java单例模式浅析 (Singleton模式)
    由歌词引发的模式思考之中篇(AbstractFactory模式)
    Java模拟FilterChain的实现 (Chain Of Responsibility模式)
    由歌词引发的模式思考之上篇(FactoryMethod模式)
    由歌词引发的模式思考之下篇(模拟Spring的BeanFactory)
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4802740.html
Copyright © 2011-2022 走看看