zoukankan      html  css  js  c++  java
  • POJ 3046 Ant Counting(递推,和号优化)

    计数类的问题,要求不重复,把每种物品单独考虑。

    将和号递推可以把转移优化O(1)。

    f[i = 第i种物品][j = 总数量为j] = 方案数

    f[i][j] = sigma{f[i-1][j-k],(k = [0,min(j,c[i])])}
    把和号展开 
    f[i][j]  :    j-0,j-1,...,j-a[i]
    f[i][j-1] :       j-1,j-2,...,j-a[i]-1
    中间部分是一样的可以避免重复计算。

    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    //#include<bits/stdc++.h>
    using namespace std;
    
    int T, A, S, B;
    const int maxt = 1e3+5, maxa = 1e5+5, mod = 1e6;
    int f[2][maxa];
    int c[maxt];
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        scanf("%d%d%d%d",&T,&A,&S,&B);
        for(int i = A; i--;){
            int x; scanf("%d",&x);
            c[x]++;
        }
        f[0][0] = f[1][0] = 1; //不选方案数为1
        for(int i = 1; i <= T; i++){
            int a = i&1, b = a^1;
            for(int j = 1; j <= B; j++){
                if(j-c[i]>0){
                    f[a][j] = ( f[a][j-1] + f[b][j] - f[b][j-1-c[i]] ) % mod;
                }else {
                    f[a][j] = ( f[a][j-1] + f[b][j] ) % mod;
                }
            }
        }
        int sum = 0, *F = f[T&1];
        for(int i = S; i <= B; i++){
            sum = (sum + F[i]) % mod;
        }
        printf("%d
    ",sum<0?sum+mod:sum);
        return 0;
    }
  • 相关阅读:
    关于互联网下的大数据及大数据对人的影响
    综合练习:词频统计=
    五星红旗
    页面性能
    前端一些常见的基础知识
    h5常见问题汇总及解决方案
    CF 184
    2013520 训练赛后总结
    斜率优化动态规划
    2013522 完美世界复赛第三场
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4887296.html
Copyright © 2011-2022 走看看