设为首页 加入收藏

TOP

POJ 3046 Ant Counting 简单DP
2014-11-23 21:27:58 来源: 作者: 【 】 浏览:1
Tags:POJ 3046 Ant Counting 简单
题意也比较简单了。
大概是:
给出T种数字。每种各有N[i]个
然后用这些数字构成一些序列, 问x长度到y长度的序列有多少种
那么就是DP了
dp[i][j] 表示前i种数字构成长度为j的序列有多少种
然后
dp[i][j] = sigma(dp[i - 1][j - k]) k的范围是0~N[i]
注意到这里的sigma(dp[i - 1][j - k]) 可以用部分和算一下
然后因为总共的数字个数可能有10W个
有1000种数组。
所以需要开滚动数组来搞
复杂度的话 是 O(sigma(num[i] * (T + 1 - i)))
最坏是1亿
#include 
#include 
#include 
#include 
#define MAXN 111111
#define INF 1000000007
using namespace std;
int dp[2][MAXN], num[1111];
int sum[MAXN], up[1111];
int main()
{
    int T, S, A, B, x;
    scanf("%d%d%d%d", &T, &A, &S, &B);
    for(int i = 1; i <= A; i++)
    {
        scanf("%d", &x);
        num[x]++;
    }
    for(int i = 1; i <= T; i++)
        up[i] = up[i - 1] + num[i];
    dp[0][0] = 1;
    int *pre = dp[0], *nxt = dp[1];
    for(int i = 1; i <= T; i++)
    {
        sum[0] = pre[0];
        for(int j = 1; j <= up[i]; j++)
            sum[j] = (sum[j - 1] + pre[j]) % 1000000;
        for(int j = 0; j <= up[i]; j++)
        {
            int tmp = max(0, j - num[i]);
            nxt[j] = (tmp == 0   sum[j] : (sum[j] - sum[tmp - 1] + 1000000));
            nxt[j] %= 1000000;
        }
        swap(nxt, pre);
    }
    int ans = 0;
    for(int i = S; i <= B; i++)
        ans = (ans + pre[i]) % 1000000;
    printf("%d\n", ans);
    return 0;
}


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 4081 Qin Shi Huang's Na.. 下一篇双向链表之C++实现

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·如何理解c语言指针和 (2025-12-27 01:19:11)
·为什么C标准库没有链 (2025-12-27 01:19:08)
·玩转C语言和数据结构 (2025-12-27 01:19:05)
·MySQL 基础入门视频 (2025-12-26 23:20:22)
·小白入门:MySQL超详 (2025-12-26 23:20:19)