首页 > 其他分享 >【P5196】【USACO19JAN】Cow Poetry G

【P5196】【USACO19JAN】Cow Poetry G

时间:2023-02-05 17:57:41浏览次数:60  
标签:digit 5005 Cow int sum while USACO19JAN P5196 getchar

前言

这是我们今天课上一道练习,结果全班就我一个过了。

看到这道题我就有了思路(

不过还是调了很久。

Solution

题意明白,不多赘述。

首先考虑对于一行诗,凑足 \(k\) 个音节有几种方案。

这个很类似于零一背包问题,和采药几乎一样。

我们设 \(f[i]\) 表示凑成 \(k\) 个音节的方案总数。

枚举最后一个单词,得到转移方程:

\[f[i]=\sum f[i-s[q]] \]

其中 \(s[q]\) 就是某个单词的长度,只有 \(i\ge s[q]\) 时才能转移。


一行诗的情况解决,然后考虑一整首诗。

由题意,两行诗押韵只考虑最后一个字母的韵部。

那么容易想到在上面的方程上加一维,表示最后一个单词的韵部,将之改为:

\[f[i][j]=\sum f[i-s[q]][p] \]

\(p\) 为任意的韵部。

聪明的你会发现,这一次转移是 \(n^2\) 的。

但是我们发现,\(p\) 的枚举是不必要的。

设 \(sum[i]=\sum f[i][p]\),则上面的转移方程变为 \(f[i][j]=\sum sum[i-s[q]]\)。

时间复杂度骤降为 \(O(n)\)。

然后是如何计算总方案数?很简单。

我们设 \(X_i\) 表示 字母 \(i\) 出现的次数。

则我们可以令某一个字母 \(i\) 押的韵是 \(j\),因为题目还没有要求不同字母押不同的韵,所以这些答案可以使用乘法原理和加法原理加起来。。

推一下柿子得到结果

\[\prod_{i=1}^{26}\sum_{p=1}^n f[k][p]^{X[i]} \]

其中 \(\Pi\) 枚举字母,\(k\) 是题目给的参数,\(p\) 是任意颜色。


代码

#include <stdio.h>
typedef long long ll;
namespace root
{
#define lc(id) (id<<1)
#define rc(id) (id<<1|1)
#define lowbit(id) (id&-id)
#define repeat(times) while(times--)
	static const int Buf_size=1<<25,Int_size=25;
	static char F[Int_size];
	static char _c;
	static bool _f;
	static int _x,__cnt;
	static const signed int base_10=10,zero(48),nine(57),flag_signed(45);
	inline int abs(const int &_x)
	{
		return _x<0?-_x:_x;
	}
	inline int max(const int &_x,const int &_y)
	{
		return _x>_y?_x:_y;
	}
	inline int min(const int &_x,const int &_y)
	{
		return _x<_y?_x:_y;
	}
	inline void swap(int &_x,int &_y)
	{
		static int _z;
		_z=_x;
		_x=_y;
		_y=_z;
		return;
	}
#define digit() (zero<=_c&&_c<=nine)
	char buf[Buf_size],*p1=buf,*p2=buf;
//#define getchar() *p1++
	static char obuf[Buf_size],*p3=obuf;
#define putchar(x) (p3-obuf<Buf_size)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
//	template<typename _Tp,const bool is_signed=false>inline void read(_Tp&_x){if(!is_signed){_x=0;_c=getchar();while(!digit())_c=getchar();while(digit()){_x=_x*10+(_c^zero);_c=getchar();}return;}else{_x=0;_f=false;_c=getchar();while(!digit()){if(_c==flag_signed)_f=true;_c=getchar();}while(digit()){_x=_x*10+(_c^zero);_c=getchar();}if(_f)_x=-_x;return;}}
	inline int read()
	{
		_x=0;
		_c=getchar();
		while(!digit())_c=getchar();
		while(digit())
		{
			_x=_x*10+(_c^zero);
			_c=getchar();
		}
		return _x;
	}
	template<typename _Tp>inline void write(_Tp _x)
	{
		if(_x<0)
		{
			putchar(flag_signed);
			_x=-_x;
		}
		if(_x<base_10)
		{
			putchar(_x^zero);
			return;
		}
		write(_x/base_10);
		putchar(_x%base_10^zero);
	}
	inline void out(int x,const char end='\n')
	{
		if(!x)
		{
			putchar(zero);
			putchar(end);
			return;
		}
		if(x<0)
		{
			x=-x;
			putchar(flag_signed);
		}
		__cnt=0;
		while(x)
		{
			F[++__cnt]=x%base_10;
			x/=base_10;
		}
		while(__cnt)
		{
			putchar(F[__cnt]^zero);
			--__cnt;
		}
		putchar(end);
		return;
	}
}//一些函数,缺省源。
namespace solve
{
	const int mod=1000000007;//记得取模
	using namespace root;
	long long base,ret;
	int repow(int a,int b)
	{
		int res=1;
		for(;b;b>>=1)
		{
			if(b&1)
				res=(ll)res*a%mod;
			a=(ll)a*a%mod;
		}
		return res;
	}//快速幂
	char now;
	long long res=1,mid;
	int sum[5005],s[5005],c[5005],t[5005],f[5005][5005];
	void main()
	{
//		fread(buf,1,Buf_size,stdin);
		register int i,j;
//		freopen("poetry.in","r",stdin);
//		freopen("poetry.out","w",stdout);
		sum[0]=1;
		register int n=read(),m=read(),k=read();
		for(i=1; i<=n; ++i)
		{
			s[i]=read();
			c[i]=read();
		}
		for(i=1; i<=k; ++i)
		{
			for(j=1; j<=n; ++j)
			{
				if(i>=s[j])
				{
					(f[i][c[j]]+=sum[i-s[j]])%=mod;
					(sum[i]+=sum[i-s[j]])%=mod;
				}
			}//这就是转移一行内的方案
		}
		for(i=1; i<=m; ++i)
		{
			++t[getchar()-'A'];//t[]就是上面的X[]
			getchar();
		}
		for(i=0; i<26; ++i)
		{
			if(t[i]==0)
				continue;
			mid=0;
			for(j=1; j<=n; ++j)
				mid+=repow(f[k][j],t[i]);
			(res*=mid%mod)%=mod;
		}//这就是最后那个柿子
		printf("%lld",res);
		return;
	}
}
int main()
{
	solve::main();
	return 0;
}

标签:digit,5005,Cow,int,sum,while,USACO19JAN,P5196,getchar
From: https://www.cnblogs.com/Syara/p/17093701.html

相关文章

  • P1472 奶牛家谱 Cow Pedigrees(DP)
    题目描述农民约翰准备购买一群新奶牛。在这个新的奶牛群中,每一个母亲奶牛都生两个小奶牛。这些奶牛间的关系可以用二叉树来表示。这些二叉树总共有N个节点(3<=N<200)......
  • P3119 [USACO15JAN]Grass Cownoisseur G 题解
    做过的原题,模拟赛时PDF里的题面实在有点难受。首先有显然结论:在一个环上反走一定是不值的,因为环上的点本来就相互可达。所以考虑缩点。缩点后的问题可以看成:求对于每一......
  • C++Day09 深拷贝、写时复制(cow)、短字符串优化
    一、std::string的底层实现1、深拷贝1classString{2public:3String(constString&rhs):m_pstr(newchar[strlen(rhs)+1]()){4}5private:6cha......
  • NC25064 [USACO 2007 Mar G]Ranking the Cows
    题目链接题目题目描述EachofFarmerJohn'sNcows(1≤N≤1,000)producesmilkatadifferentpositiverate,andFJwouldliketoorderhiscowsaccording......
  • 213. 字典序最小问题 Best Cow Line(挑战程序设计竞赛)
    地址https://www.papamelon.com/problem/213给定一个字符SS,长度为NN。由SS构成出新的字符串TT,长度也为NN。起初TT是一个空串,然后执行NN次操作,每次操作有两种......
  • [USACO22DEC] Cow College B 题解
    洛谷P8897AcWing4821题目描述有\(n\)头奶牛,每头奶牛愿意交的最大学费位\(c_i\),问如何设置学费,可以使赚到的钱最多。\(1\len\le10^5,1\lec_i\le10^6\)做法分析......
  • IfcOwnerHistory
    IfcOwnerHistory实体定义IfcOwnerHistory定义所有历史和标识相关信息。为了提供快速访问,它直接连接到所有独立的对象、关系和属性。 IfcOwnerHistory用于标识创建和拥......
  • [oeasy]python0036_牛说_cowsay_小动物说话_asciiart_figlet_lolcat_管道(祝大家新年
    ​ 牛说(cowsay)回忆上次内容上次我们研究了shell脚本的编程并且在shell中实现了循环语句延迟命令清屏命令python命令figlet命令​编辑还能整点什么......
  • POJ 3176 Cow Bowling
    POJ3176CowBowling题意:给出一个数字三角形,每个分叉路口可以选择一条道路向下走,获得路上的点的权值。求可以获得的最大权值是多少?思路:从上向下走和从下向上走是一......
  • POJ 3278 Catch That Cow(BFS)
    POJ3278CatchThatCow​ 现在你在一个数轴上的位置x,位置k上有一头牛,你要抓住这头牛,也就是走到位置k上。那怎么走呢?你有两种走路的方法,一种是从x移动到\(2\tim......