• 4月22日


    poj3046

    题意:有n种数a个,求分成s份到b份总共有多少种分法

    分析:dp[i+1][j]表示从前i个物品中取出j个共有多少种取法,则前i-1中必然取出的是j-k个,(0<=k<=min(j,vis[i])),所以

    dp[i+1][j]=Σdp[i][j-k]=Σdp[i][j-1-k]+dp[i][j]-dp[i][j-1-vis[i]]=dp[i+1][j-1]+dp[i][j]-dp[i][j-1-vis[i]],推到过程详见《调整程序设计》68到69页,注意此处要用滚动数组,不然会爆掉

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=1002;
    15 const int mod=1000000;
    16 const int maxm=100002;
    17 int vis[maxn];
    18 int t,a,s,b;
    19 int main()
    20 {
    21     while(cin>>t>>a>>s>>b)
    22     {
    23         memset(vis,0,sizeof(vis));
    24         for(int i=0;i<a;i++)
    25         {
    26             int x;
    27             scanf("%d",&x);
    28             vis[x-1]++;
    29         }
    30         int dp[2][maxm];
    31         dp[0][0]=1;
    32         dp[1][0]=1;
    33         for(int i=0;i<t;i++){
    34             for(int j=1;j<=b;j++){
    35                 if(j-1-vis[i]>=0)
    36                     dp[(i+1)&1][j]=(dp[(i+1)&1][j-1]+dp[i&1][j]-dp[i&1][j-1-vis[i]]+mod)%mod;
    37                 else{
    38                     dp[(i+1)&1][j]=(dp[(i+1)&1][j-1]+dp[i&1][j])%mod;
    39                 }
    40             }
    41         }
    42         long long cnt=0;
    43         for(int cas=s;cas<=b;cas++)
    44         {
    45             cnt=(cnt+dp[t&1][cas])%mod;
    46         }
    47         cout<<cnt%mod<<endl;
    48     }
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    天使玩偶
    CSPS 2019 Day1 T2 括号树
    权值线段树2(求逆序对)
    第一篇blog
    [GXOI/GZOI2019]特技飞行
    Mokia 摩基亚
    概率基本概念
    第一课:认识Richfaces
    第四课:JSF\Richfaces中使用javabean
    第二课:安装Richfaces Demo
  • 原文地址:https://www.cnblogs.com/wolf940509/p/5420885.html
Copyright © 2020-2023  润新知