zoukankan      html  css  js  c++  java
  • POJ 3046 Ant Counting

    题意:给出T种数字。每种各有N[i]个。然后用这些数字构成一些序列, 问x长度到y长度的序列有多少种

    思路:

    dp[i][j] 表示前i种数字构成长度为j的序列有多少种。

    dp[i][j] = sigma(dp[i - 1][j - k]) k的范围是0~N[i]    

    //前i-1个家族配成j-k的集合,每一个集合都加入家族i的k只的蚂蚁,累加得到前i个家族配成j的集合的个数:

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <string>
    #include <algorithm>
    using namespace std;
    #define MOD 1000000
    int family[1001];
    int dp[1001][10001];
    
    int main()
    {
        int T,A,S,B;
        cin>>T>>A>>S>>B;
        for(int i=0;i<A;i++)
        {
            int index;
            cin>>index;
            ++family[index];
        }
        dp[0][0]=1;// 空集的个数为一
        int totel=family[0];
        for(int i=1;i<=T;i++)
        {
            totel+=family[i]; // 前i个家族一共有多少只蚂蚁
            for(int k=0;k<=family[i];k++)
            {
                for(int j=totel;j>=k;j--)
                {
                    dp[i][j]=(dp[i][j]+dp[i-1][j-k])%MOD; // 前i-1个家族配成j-k的集合们每一个集合都放入k只
                }
            }
        }
        int result=0;
        for (int i = S; i <= B; ++i)
    	{
    		result = (result + dp[T][i]) % MOD;
    	}
    	cout << result << endl;
        return 0;
    }

    因为总共的数字个数可能有10W个,有1000种数组。所以需要开滚动数组来做

    //由于dp数组每次都是i和i-1,所以可以利用奇偶性实现滚动数组:
    int dp[2][100001];
    
    int cur = i & 1;
    int pre = (i - 1) & 1;
    memset(dp[cur], 0, sizeof(dp[cur]));
    dp[cur][j] = (dp[cur][j]+ dp[pre][j - k]) % MOD;
    
  • 相关阅读:
    Hive伪分布式下安装
    Hadoop单机和伪分布式安装
    Spark 键值对RDD操作
    Scala入门:从HelloWorld开始【源码及编译】
    Spark RDD编程核心
    Scala 元组
    剑指offer(7):斐波那契数列
    剑指offer(13):调整数组顺序使奇数位于偶数前面
    剑指offer(21):二维数组中的查找
    解决IEDA web项目控制台中文乱码
  • 原文地址:https://www.cnblogs.com/demian/p/7367497.html
Copyright © 2011-2022 走看看