zoukankan      html  css  js  c++  java
  • 【动态规划】统计蚂蚁 (ants)

    题目

    描述

    蚂蚁山上有T(1<=T<=1,000)种蚂蚁,标记为1..T,每种蚂蚁有N_i只蚂蚁(1<=N_i<=100),现有A(A<=5000)只蚂蚁,从中选出S,S+1,…,B(1<=S<=B<=A)只蚂蚁一共有多少种选法?
    如有5只蚂蚁分别为{1,1,2,2,3},一共有3种蚂蚁,每一种蚂蚁的数量分别为2,2,1,以下是选不同数量蚂蚁的方法:
    1个蚂蚁3种选法 : {1}{2}{3}
    2个蚂蚁5种选法 : {1,1}{1,2}{1,3}{2,2}{2,3}
    3个蚂蚁5种选法 : {1,1,2}{1,1,3}{1,2,2}{1,2,3}{2,2,3}
    4个蚂蚁3种选法 : {1,2,2,3}{1,1,2,2}{1,1,2,3}
    5个蚂蚁1种选法 : {1,1,2,2,3}
    你的任务是从中选S..B只蚂蚁的方法总和。

    输入

    第一行: 4个空格隔开的整数: T, A, S和B;
    第2到A+1行:每行一个整数表示蚂蚁的种类。

    输出

    输出从A只蚂蚁中选出S..B只蚂蚁的方法数,答案保留后6位。

    样例输入

    3 5 2 3
    1
    2
    2
    1
    3
    

    样例输出

    10
    

    大意

    有 A 个 T 种物品,求取 \(i \in [S,B]\)共有多少种方法,答案取模 1000000

    题解

    首先用一个桶存储存每种蚂蚁的数量,设为 x[] 。

    60分左右

    动态规划,设 F[i][j] 为前 i 种物品选 j 个的方案数。则
    \(F_{0,0}=1\)
    \(F_{i,j}=\sum_{k=0}^{\min{(j,x_i)}} F_{i-1,j-k}\)
    但是这样的时间复杂度是 \(O(T\sum x_i)\) ,会超时。

    满分

    上面的 \(F[i][]\) 都是从 \(F[i-1][]\) 得来的,因此我们想到了前缀和
    \(S[i][j]\) 表示前 i 种物品取 0~i 个时的方案总和
    前缀和我们并不陌生, \(S_{i,j}=S_{i,j-1}+F_{i,j}\)
    那怎么求 \(F[i][j]\) 呢?
    60 分做法时的公式得知,\(F[i][j]\) 等于 \(F[i-1][j-k]\)\(F[i-1][j]\) 的和
    这一段和就是 \(S_{i-1,j}-S_{i-1,j-k-1}\) ,也就是 \(S_{i-1,j}-S_{i-1,j-\min(x[i],j)-1}\)
    最后注意初始化
    \(S[2\textit{~}A][0]=1\)
    \(S[0][0\textit{~}T]=\min{(x[1],0\text{~}T)+1}\)
    就可以通过了

    标程

    #include<bits/stdc++.h>
    #define rg register int
    using namespace std;
    const int mod=1000000;
    int n,m,l,r,t,x[5005],f[1005][5005],s[1005][5005],ans;
    int main(){
    	freopen("ants.in","r",stdin);
    	freopen("ants.out","w",stdout);
    	scanf("%d%d%d%d",&n,&m,&l,&r);
    	for(rg i=1;i<=m;i++) scanf("%d",&t),++x[t];
    	for(rg i=0;i<=m;i++) s[1][i]=min(i,x[1])+1;
    	for(rg i=2;i<=n;i++){
    		s[i][0]=1;
    		for(rg j=1;j<=m;j++){
    			f[i][j]=(s[i-1][j]-s[i-1][j-min(x[i],j)-1])%mod;
    			s[i][j]=(s[i][j-1]+f[i][j])%mod;
    		}
    	}
    	for(rg i=l;i<=r;i++) ans=(ans+f[n][i])%mod;
    	printf("%d",ans);
    }
    
  • 相关阅读:
    TensorFlow设置GPU占用量
    与服务器同步工程(expect脚本)
    C/C++中#pragma once的使用
    sublime text 3 快捷键大全
    Sublime Text 3 注册码
    如何用diff比较两个文件夹下的内容
    Error in building opencv with ffmpeg
    opencv: Rotate image by 90, 180 or 270 degrees
    初识HTTPS
    Unity3D之Mecanim动画系统学习笔记(十一):高级功能应用
  • 原文地址:https://www.cnblogs.com/KonjakLAF/p/13330090.html
Copyright © 2011-2022 走看看