zoukankan      html  css  js  c++  java
  • DP:Ant Counting(POJ 3046)

                      

                        数蚂蚁

      题目大意:一只牛想数蚂蚁,蚂蚁分成很多组,每个组里面有很多只蚂蚁,现在问你有多少种组合方式

           (说白了就是问1,1,1,...,2...,3...,4...)这些东西有多少种排列组合方式

      这一道题我一开始想着去用矩阵乘法去做了,结果怎么想怎么不对,后来想着,如果对1,2,3,这些看成背包会怎么样呢?最后结果就压在最后一个背包就可以了

      这么一想就懂了,其实就是要你找到递推关系,直接画一个矩阵拉几个箭头就很容易地看出来,对于一个矩阵,dp[i][j]等于dp[i-1][k] j-f[i]<=k<j的所有之和

      因为我们是一个格子一个格子地数的,所以会有重复的计算,那么就弄一个队列区间维护长度就可以了,每一次循环减掉一开始的值,增加j的值

      状态转移方程

        dp[1][k] = 1 0<=k<=f[1]

        dp[i][j]= ∑dp[i-1][k]  j-f[i]<=k<j&& i<=f_sum

      这题直接用滚动数组也是很快的

      

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define MAX_N 1001
     4 #define MAX_A 100
     5 #define M 1000000
     6 
     7 static int families[MAX_N];
     8 static int dp1[MAX_N *MAX_A];
     9 static int dp2[MAX_N *MAX_A];
    10 
    11 void Search(const int, const int, const int);
    12 
    13 int main(void)
    14 {
    15     int families_sum, ants_sum, S, E, i, tmp;
    16     while (~scanf("%d%d%d%d", &families_sum, &ants_sum, &S, &E))
    17     {
    18         for (i = 1; i <= ants_sum; i++)
    19         {
    20             scanf("%d", &tmp);
    21             families[tmp]++;
    22         }    
    23         Search(families_sum, S, E);
    24     }
    25     return 0;
    26 }
    27 
    28 void Search(const int families_sum, const int S, const int E)
    29 {
    30     int i, j, L, now_amx, ans = 0;
    31     int *exchange = NULL, *now = dp2, *prev = dp1;
    32 
    33     now[0] = 1;
    34     for (i = 0; i <= families[1]; i++)//基准情况
    35         prev[i] = 1;
    36     now_amx = families[1];
    37     for (i = 2; i <= families_sum; i++)
    38     {
    39         now_amx += families[i];
    40         for (j = 1, L = 1; j <= families[i]; j++)//先处理L<families[i]的情况
    41         {
    42             now[j] = (prev[j] + L) % M;
    43             L += prev[j] % M;
    44         }
    45         for (;j <= now_amx; j++)
    46         {
    47             L -= prev[j - families[i] - 1];
    48             now[j] = (prev[j] + L) % M;
    49             L += prev[j] % M;
    50         }
    51         exchange = prev; prev = now; now = exchange;
    52     }
    53     for (i = S; i <= E; i++)
    54         ans = (ans + prev[i]) % M;
    55     printf("%d
    ", ans);
    56 }

       

  • 相关阅读:
    DWZ集成的xhEditor编辑器浏览本地图片上传的设置
    微服务看门神-Zuul
    OAuth2.0最简向导
    打造个人IP: 开源项目网站构建框架
    提前体验让人"回归Windows怀抱"的Windows Terminal
    ToB蓝海的台阶-PaaS,SaaS技术详解
    再不了解PostgreSQL,你就晚了之PostgreSQL主从流复制部署
    Netty实现高性能IOT服务器(Groza)之精尽代码篇中
    使用keepalived做High Available(HA)
    Nginx 常用配置方式说明
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/4837066.html
Copyright © 2011-2022 走看看