• P7154 [USACO20DEC] Sleeping Cows P(DP)


    主要是状态设计比较难想,但其实可以理性地推出来。

    P7154 [USACO20DEC] Sleeping Cows P

    考虑最终一个合法状态是怎么样的:一定是一堆小牛棚,一堆大奶牛,最大的牛棚小于最小的奶牛。

    这启发我们将所有牛和牛棚放在一起,那么一定先选择牛棚,后选择奶牛。

    我们加入一个牛棚后的决策情况:

    • 将这个牛棚与前面准备匹配但没有匹配的牛匹配,需要记录前面有多少牛。
    • 将这个牛棚抛弃,这需要保证前面没有被抛弃的奶牛。

    加入一头牛的抉择情况:

    • 将这个奶牛加入匹配之列。
    • 将这个奶牛抛弃。

    那么设 \(dp_{i,j,0/1}\) 表示到(混合后)第 \(i\) 个为止,在匹配队列中的奶牛有 \(j\) 头,是否有奶牛已经被抛弃的方案数。

    \(\bigstar\texttt{Attention}\):注意排序的时候要将相同大小的物品奶牛放在前面。

    #define Maxn 6005
    #define mod 1000000007
    int n,cnt;
    int dp[Maxn][Maxn][2];
    struct Object
    {
    	int opt,val;
    	Object(int Opt=0,int Val=0):opt(Opt),val(Val){}
    	bool friend operator < (Object x,Object y)
    		{ return (x.val!=y.val)?(x.val<y.val):(x.opt<y.opt); }
    }a[Maxn];
    int main()
    {
    	n=rd();
    	for(int i=1,x;i<=n;i++) x=rd(),a[++cnt]=Object(0,x);
    	for(int i=1,x;i<=n;i++) x=rd(),a[++cnt]=Object(1,x);
    	sort(a+1,a+cnt+1),dp[0][0][0]=1;
    	for(int i=1;i<=cnt;i++) for(int j=0;j<=i;j++)
    	{
    		if(a[i].opt)
    		{
    			dp[i][j][0]=1ll*dp[i-1][j+1][0]*(j+1)%mod;
    			dp[i][j][1]=1ll*dp[i-1][j+1][1]*(j+1)%mod;
    			(dp[i][j][0]+=dp[i-1][j][0])%=mod;
    		}
    		else
    		{
    			if(j) dp[i][j][0]=dp[i-1][j-1][0];
    			if(j) dp[i][j][1]=dp[i-1][j-1][1];
    			(dp[i][j][1]+=(1ll*dp[i-1][j][0]+1ll*dp[i-1][j][1])%mod)%=mod;
    		}
    	}
    	printf("%d\n",(dp[cnt][0][0]+dp[cnt][0][1])%mod);
    	return 0;
    }
    
  • 相关阅读:
    MySQL中MyISAM为什么比InnoDB查询快
    .Net Core导入千万级数据至Mysql
    细说MySql索引原理
    原生Swagger界面太low(推荐)
    开源分布式调度系统分享(ScheduleMaster)
    tfs agent cicd 自动编译 xcpoy失败
    .net 网站
    Android App Arch
    Android 多进程引发的一次crash
    Scrapy 抓取数据入门操作
  • 原文地址:https://www.cnblogs.com/EricQian/p/16585880.html
Copyright © 2020-2023  润新知