球调码农题
查看原帖
球调码农题
313716
EgLund楼主2021/2/8 13:26

RT,

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define roF(i,l,r) for(int i=r;i>=l;i--)
//github.com/sy201901y/syone-lib-cppjy/blob/main/basic_definations.h

using namespace std;

const int N=25;

int T,n;
int dp[N][N][N][N][3];
int sum[5],tot[15];
int ans;
void Pre_dp()
{
	int now;memset(dp,0x3f,sizeof(dp));//inition for DP
	For(l,0,n)For(k,0,n)For(i,0,n)For(j,0,n)For(m,0,2)//all cases
	{
		now=n;
		if(i)now=min(now,dp[i-1][j][k][l][m]+1);
		if(j)now=min(now,dp[i][j-1][k][l][m]+1);
		if(k)now=min(now,dp[i][j][k-1][l][m]+1);
		if(l)now=min(now,dp[i][j][k][l-1][m]+1);
		if(m)now=min(now,dp[i][j][k][l][m-1]+1);
		//one
		
		if(m==2)now=min(now,dp[i][j][k][l][m-2]+1);
		//Joker*2
		
		if(k&&i)now=min(now,dp[i-1][j][k-1][l][m]+1);
		if(k&&m)now=min(now,dp[i][j][k-1][l][m-1]+1);
		//3+1
		
		if(k&&j)now=min(now,dp[i][j-1][k-1][l][m]+1);
		//3+2
		
		if(l&&i>=2)now=min(now,dp[i-2][j][k][l-1][m]+1);
		if(l&&i&&m)now=min(now,dp[i-1][j][k][l-1][m-1]+1);
		if(l&&m==2)now=min(now,dp[i][j][k][l-1][m-2]+1);
		if(l&&j)   now=min(now,dp[i][j-1][k][l-1][m]+1);
		if(l&&j>=2)now=min(now,dp[i][j-2][k][l-1][m]+1);
		if(l>=2)   now=min(now,dp[i][j][k][l-2][m]+1);
		//4+2
		
		if(l)now=min(now,dp[i+1][j][k+1][l-1][m]);
		if(k)now=min(now,dp[i+1][j+1][k-1][l-1][m]);
		//break series
		
		dp[i][j][k][l][m]=min(dp[i][j][k][l][m],now);
	}
}//prework

int ID(int x)
{
	if(x==0)return 14;//joker
	if(x==2)return 13;
	if(x==1)return 12;
	return x-2;
}//id of card

void dfs(int now)
{
//cout<<now<<endl;
	if(now>=ans)return;
	bool check;int lim;
	For(k,1,3)For(i,1,12)
	{
		check=0;
		if(k==1)lim=5;
		if(k==2)lim=3;
		if(k==3)lim=2;
		For(len,lim,12-i+1)
		{
			For(j,1,len)if(tot[i+j-1]<k){check=1;break;}
			if(!check)
			{
				For(j,1,len)tot[i+j-1]-=k;
				dfs(now+1);
				For(j,1,len)tot[i+j-1]+=k;
			}
			else break;
		}
	}
	memset(sum,0,sizeof(sum));
	For(i,1,13)sum[tot[i]++];
	ans=min(ans,now+dp[sum[1]][sum[2]][sum[3]][sum[4]][tot[14]]);
}//dfs to settle lines

int main()
{
	cin>>T>>n;
	Pre_dp();
	while(T--)
	{
		memset(tot,0,sizeof(tot));
		int num,color;ans=n;
		For(i,1,n)cin>>num>>color,tot[ID(num)]++;
		dfs(0);
		cout<<ans<<endl;
	}
}
2021/2/8 13:26
加载中...