Toyota Programming Contest 2024#7(AtCoder Beginner Contest 362)

wlesq發表於2024-07-14

這場比賽還是比較水的
A,B,C跳過
D題dij把點權和邊權都轉換為邊權即可
E題DP
可以用\(map\)存一下等差數列的差
先說\(O(n^4)\),\(f_{len,i,j,t}\)分別表示長度,現在在\(i\),上一個在\(j\)
顯然動態轉移方程就有了\(f_{len,i,j,k}=\sum_{k=1}^{k=j-1} f_{len-1,j,k,t}\)

點選檢視程式碼
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define lid (rt<<1)
#define rid (rt<<1|1)
#define speed() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define int long long
using namespace std;
const int N = 85,mod=998244353;
ll n,m,a[N],ans[N];
map <ll,ll> f[N][N][N];
main()
{
	speed();
	cin>>n;
	ll mi=1e9,mx=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];mi=min(mi,a[i]);
		mx=max(mx,a[i]);
	}
	for(int i=1;i<=n;i++)
	{
//		f[1][i][i][0]=1;
		for(int j=1;j<=i-1;j++)
		{
			f[2][i][j][(ll)(a[i]-a[j])]=1;
		}
	}
	for(int le=3;le<=n;le++)
	{
//		ll ans=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=i-1;j++)
			{
				ll t=a[i]-a[j];
					for(int k=1;k<=j-1;k++)
						if(a[j]-a[k]==t)
							f[le][i][j][t]=(f[le-1][j][k][t]+f[le][i][j][t])%mod;
				ans[le]=(ans[le]+f[le][i][j][t])%mod;
	//			cout<<le<<" "<<f[le][i][j][t]<<endl;
				
			}				
		}	
//		cout<<le<<" "<<ans<<endl;	
	}

	for(int k=1;k<=n;k++)
	{
		if(k==1)cout<<n<<" ";
		else if(k==2)cout<<1ll*n*(n-1)/2<<" ";
		else
		{
//			ll ans=0;
//			for(int i=mi;i<=mx;i++)

			cout<<ans[k]<<" ";
		}
	}
	return 0;
}

然後就水過了,其實我們還可以壓縮提下狀態,\(map\)結構體
把前三維全部壓成一維,程式碼如下(借的\(qinyun\)對的)

點選檢視程式碼
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef double db;
#define CLOSE() ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define GG puts("============================")
#define Ct(x); if(x)puts("Yes");else puts("No");
#define CT(x); if(x)puts("YES");else puts("NO");
#define ct(x); if(x)puts("yes");else puts("no");
#define pii pair<int,int>
#define fi first
#define se second
#define re register
#define int ll
#define pt(x) putchar(x)
#define M(x,y) memset(x,y,sizeof x)

inline ll read()
{
	re ll ans=0;bool f=0;re char ch=getchar();
	for(;!isdigit(ch);ch=getchar())if(ch=='-')f=1;
	for(;isdigit(ch);ch=getchar())ans=(ans<<1)+(ans<<3)+(ch^48);
	return f?~ans+1:ans;
}

void print(ll n)
{
	if(n<0)putchar('-'),n=-n;
	if(n>9)print(n/10);
	putchar(n%10+48);
}

void _print(ll n)
{
	print(n);
	pt(' ');
}

void __print(ll n)
{
	print(n);
	pt('\n');
}

struct node
{
	int i,d,len;
	bool operator < (const node a) const
	{
		if(i!=a.i)return i<a.i;
		if(d!=a.d)return d<a.d;
		return len<a.len;
	}
	
	
};

const int mod=998244353;
map<node,int>mp;
int a[100],t[100],ans[100];

signed main()
{
	int n=read();
	for(int i=1;i<=n;++i)
		a[i]=read();
	
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<i;++j)
			for(int l=1;l<=n;++l)
			{
				if(l==1)++mp[(node){i,a[i]-a[j],l}],t[l+1]=(t[l+1]+1)%mod;
				else mp[(node){i,a[i]-a[j],l}]=(mp[(node){i,a[i]-a[j],l}]+mp[node{j,a[i]-a[j],l-1}])%mod,t[l+1]=(t[l+1]+mp[node{j,a[i]-a[j],l-1}])%mod;
//				if(l==2)cout<<i<<' '<<j<<' '<<t[3]<<" "<<mp[node{j,a[i]-a[j],l-1}]<<endl;
//				cout<<i<<" "<<j<<' '<<mp[{3,0,1}]<<endl;
			}
	}
	
	_print(n);
	for(int i=2;i<=n;++i)
		_print(t[i]);
	
	return 0;
}
/*
10
1 1 1 1 1 1 1 1 1 1

4
1 1 1 1
*/

F題 鴿了

G題
AC自動機板子

相關文章