首页 > 其他分享 >Educational Codeforces Round 164 (Rated for Div. 2) D

Educational Codeforces Round 164 (Rated for Div. 2) D

时间:2024-04-13 17:22:25浏览次数:15  
标签:Educational Rated ll 小球 Codeforces 然后 枚举 数量 就是

因为理解错了题目导致我没错出来。我理解为有两个人取球,每个人每次都是取一组,也就是一组的球必须要放在一个人手里。。因为我之前做的一个背包是这个样子的。这就导致了,我认为每次转移所需要的信息是比实际要的多很多的,直接导致我没法设计一个正常的dp。
然后炸了。。。

好烦。。。完全可以上1800的一场,结果因为这种题意理解的问题寄了。
掉了25分。

这个其实也是因为之前做到的题目导致的吧。。给我的思维带来了一个奇妙的导向。很蠢。
以后其实遇到了这种完全没思路,但是大家又都会做的时候,可以把思维的每一个环节都仔细考虑一下,是不是题读错了之类的错。。。
太傻了。

其实就是背包,然后随便推推就没了。思路就是之前的那些,找到一个东西,固定它能够使得代价可统计。就没了。

然后因为取模的原因死在了test13,又因为下取整的原因死在了test5,这个下取整一定要带括号。。。不然会变化的。

具体做法就是先让\(a[i]\)从小到大排序,设\(f[i][j]\)表示前\(i\)类物品,任意取,最终数量有\(j\)个的方案数。
然后转移就是\(f[i][j]=f[i-1][j]+f[i][j-a[i]](0\leq j \leq tot),其中tot表所有球的数量和\)
然后我们从1枚举到n,枚举这次把哪一类小球产生的价值记入答案,因为我们的\(a[i]\)是从小到大排序的,所有每次加入的肯定都是当前这个方案里面数量最多的小球种类。
我们考虑怎么统计答案(其实这个应该是要先考虑,然后才有的这个做法),对于每一个种类的小球,我们枚举前面已经选取的多少个小球,设这个数字为\(sum\),而\(a[i]\)就是小球数量最多的种类的数量,当\(a[i]\geq sum\)的时候,产生的代价就是\(a[i]\times方案数\),而当\(a[i]<sum\)的时候,答案其实就是\((a[i]+sum)/2上取整 \times 方案数\),可以证明,如果答案不是这个,就说明\(a[i]\)前,也就是\(a[1...(i-1)]\)里面有比\(a[i]\)更大数字,而我们排过序了,这个是不可能的。所以是一定成立的。那其实就是一个计数背包。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
	char c=getchar();ll a=0,b=1;
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
ll n,a[5001],f[5001][5001];
const ll Mod=998244353;
int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	ll T=read();
//	while(T--)
//	{
	n=read();ll all=0;ll ans=0;
	for(ll i=1;i<=n;i++)a[i]=read(),all+=a[i];
	sort(a+1,a+1+n);
	f[0][0]=1;
	for(ll i=1;i<=n;i++)
	{
		for(ll j=0;j<=all;j++)
		{
			f[i][j]=(f[i-1][j]);
			if(j>=a[i])f[i][j]+=f[i-1][j-a[i]];
			f[i][j]%=Mod;
		}
	}
	for(ll i=1;i<=n;i++)
	{
		for(ll j=0;j<=all;j++)
		{
			if(f[i-1][j]!=0)
			{
				if(j<=a[i])
				{
					ans+=a[i]*f[i-1][j];
				}
				else
				{
					ans+=f[i-1][j]*((j+a[i]+1)/2);
				}
				ans%=Mod;
			}
		}
	}
	cout<<ans%Mod<<endl;
//	}
	return 0;
}
/*
5
6 6 19 25 44


*/

标签:Educational,Rated,ll,小球,Codeforces,然后,枚举,数量,就是
From: https://www.cnblogs.com/HLZZPawa/p/18133106

相关文章

  • [CF1954] Educational Codeforces Round 164 (Rated for Div. 2) 题解
    [CF1954]EducationalCodeforcesRound164(RatedforDiv.2)题解A.PaintingtheRibbon最优策略是染\(\lceil\dfrac{n}{m}\rceil\)个颜色,然后Bob会把剩下的都染成这个颜色voidwork(){intn,m,k,c;cin>>n>>m>>k;c=(n+m-1)/m;......
  • [CF1942] CodeTON Round 8 (Div. 1 + Div. 2, Rated, Prizes! A~E 题解
    [CF1942]CodeTONRound8(Div.1+Div.2,Rated,Prizes!A~E题解A.FarmerJohn'sChallenge只有两种情况,一种是单调递增,这时\(k=1\),另一种是所有数都相同,这时\(k=n\)。B.BessieandMEX首位可以确定,然后从前往后增量构造\(p\)即可。voidwork(){cin>>......
  • Educational Codeforces Round 36 (Rated for Div. 2)
    EducationalCodeforcesRound36(RatedforDiv.2)A直接枚举即可#include<bits/stdc++.h>intmain(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);intn,k;std::cin>>n>>k;intans=1e9;for(int......
  • Educational Codeforces Round 154 (Rated for Div. 2)
    B和C写的太慢了。吃了不该吃的罚时,C还莫名其妙的T了一发,另一发也是不应该T的。B连想了两个假做法,然后甚至都实现了,然后过不了样例,再基于这两个才想到了真做法。当时的思路已经有些模糊了,但是确实是写的太慢了,而且\(O(n^2)\)的限制给的也很宽裕,但是我居然还傻乎乎的去先\(O(n^2)......
  • Codeforces Round 893 (Div. 2) D
    链接第一个想法:\(O(n^2)\)可过,很明显,我可以直接统计出来每一个位置作为中心,向两边扩展最多能得到的多少个连续的1。这个想法是不成熟的,但是我甚至开始写了。哎。然后写了140行,发现寄了,思路太复杂,完全用不了。这里就引出了一个事情:太复杂的思路其实不能算是思路,因为表达是不可能......
  • Codeforces Round 938 (Div. 3) A-H 题解
    A-YogurtSaleSolution当\(2a>b\)时,显然用\(a\)来买两个比较好,否则就用\(b\)来买两个比较好Code#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;inta,b;cin>>a>>b;b=min(b,a*2);int......
  • Codeforces-182E 题解
    Vasyahasrecentlyboughtsomelandanddecidedtosurrounditwithawoodenfence.Hewenttoacompanycalled"Woodenboard"thatproduceswoodenboardsforfences.Vasyareadinthecatalogofproductsthatthecompanyhasatitsdisposal\(......
  • Codeforces Round 938 (Div. 3)题解(A-E)
    A.YogurtSale题意:输入一份酸奶a元,两份b元,求买n份酸奶最少要多少钱。#include<iostream>#include<string>#include<cstring>#include<algorithm>usingnamespacestd;typedeflonglongll;constintN=1e6+7;voidsolve(){ intn,a,b;cin>>n>>......
  • Codeforces Round 938 (Div. 3) E
    链接有点意思的题目。首先可以得到的一个结论就是,如果k能够完成,那唯一的操作方法就是从前往后,遇到0就使用,把这个点变成1。那么我们就能够做到O(n)验证了,然后发现O(n^2)可以接受,就过了。但是我因为滥用数据结构,导致我认为验证需要O(nlogn)然后5000又刚刚好跑不过去。所以觉得......
  • Codeforces Global Round 25 E
    链接其实还是很好写的。其实很明显,手玩一下就可以发现只用1次或者两次就可以分完,否则就是以下3中情况。aaaaaaaaabaaaabababa这个证明很简单。难在怎么想。其实就是手玩以下,看看怎么样分不了,然后就可以了。样例具有一定的迷惑性,还是很好解决的。然后马拉车数组清空要清到......