UVA 10118 Free Candies

#include<bits/stdc++.h>
using namespace std;
int a[42][6],dp[42][42][42][42],baslen[42][42][42][42],basket[42][42][42][42][6];
bool b[42][42][42][42];
void cal1(int i,int j,int q,int p){
	if(i==0)return;
	if(baslen[i-1][j][q][p]==5||b[i-1][j][q][p]==0)return;
	int len,t[6];
	for(len=1;len<=baslen[i-1][j][q][p];len++)
		t[len]=basket[i-1][j][q][p][len];
	t[len]=a[i][1];
	int ok=0,bj1=0,bj2=0;
	for(int k1=1;k1<len;k1++)
	    for(int k2=k1+1;k2<=len;k2++)
	    	if(t[k1]==t[k2]){
	    		ok=1;
	    		bj1=k1;
	    		bj2=k2;
	    	}
	if(dp[i-1][j][q][p]+ok>dp[i][j][q][p]||dp[i][j][q][p]==0){
		dp[i][j][q][p]=dp[i-1][j][q][p]+ok;
		baslen[i][j][q][p]=0;
		for(int k=1;k<=len;k++)
			if(k!=bj1&&k!=bj2)
				basket[i][j][q][p][++baslen[i][j][q][p]]=t[k];
	}
}
void cal2(int i,int j,int q,int p){
	if(j==0)return;
	if(baslen[i][j-1][q][p]==5||b[i][j-1][q][p]==0)return;
	int len,t[6];
	for(len=1;len<=baslen[i][j-1][q][p];len++)
		t[len]=basket[i][j-1][q][p][len];
	t[len]=a[j][2];
	int ok=0,bj1=0,bj2=0;
	for(int k1=1;k1<len;k1++)
	    for(int k2=k1+1;k2<=len;k2++)
	    	if(t[k1]==t[k2]){
	    		ok=1;
	    		bj1=k1;
	    		bj2=k2;
	    	}
	if(dp[i][j-1][q][p]+ok>dp[i][j][q][p]||dp[i][j][q][p]==0){
		dp[i][j][q][p]=dp[i][j-1][q][p]+ok;
		baslen[i][j][q][p]=0;
		for(int k=1;k<=len;k++)
			if(k!=bj1&&k!=bj2)
				basket[i][j][q][p][++baslen[i][j][q][p]]=t[k];
	}
}
void cal3(int i,int j,int q,int p){
	if(q==0)return;
	if(baslen[i][j][q-1][p]==5||b[i][j][q-1][p]==0)return;
	int len,t[6];
	for(len=1;len<=baslen[i][j][q-1][p];len++)
		t[len]=basket[i][j][q-1][p][len];
	t[len]=a[q][3];
	int ok=0,bj1=0,bj2=0;
	for(int k1=1;k1<len;k1++)
	    for(int k2=k1+1;k2<=len;k2++)
	    	if(t[k1]==t[k2]){
	    		ok=1;
	    		bj1=k1;
	    		bj2=k2;
	    	}
	if(dp[i][j][q-1][p]+ok>dp[i][j][q][p]||dp[i][j][q][p]==0){
		dp[i][j][q][p]=dp[i][j][q-1][p]+ok;
		baslen[i][j][q][p]=0;
		for(int k=1;k<=len;k++)
			if(k!=bj1&&k!=bj2)
				basket[i][j][q][p][++baslen[i][j][q][p]]=t[k];
	}
}
void cal4(int i,int j,int q,int p){
	if(p==0)return;
	if(baslen[i][j][q][p-1]==5||b[i][j][q][p-1]==0)return;
	int len,t[6];
	for(len=1;len<=baslen[i][j][q][p-1];len++)
		t[len]=basket[i][j][q][p-1][len];
	t[len]=a[p][4];
	int ok=0,bj1=0,bj2=0;
	for(int k1=1;k1<len;k1++)
	    for(int k2=k1+1;k2<=len;k2++)
	    	if(t[k1]==t[k2]){
	    		ok=1;
	    		bj1=k1;
	    		bj2=k2;
	    	}
	if(dp[i][j][q][p-1]+ok>dp[i][j][q][p]||dp[i][j][q][p]==0){
		dp[i][j][q][p]=dp[i][j][q][p-1]+ok;
		baslen[i][j][q][p]=0;
		for(int k=1;k<=len;k++)
			if(k!=bj1&&k!=bj2)
				basket[i][j][q][p][++baslen[i][j][q][p]]=t[k];
	}
}
int main(){
	int n,i,j,q,p,ans;
	while(scanf("%d",&n)&&n){
		for(i=1;i<=n;i++)
			for(j=1;j<=4;j++)
				scanf("%d",&a[i][j]);
		ans=0;
		memset(dp,0,sizeof(dp));
		memset(b,0,sizeof(b));
		for(i=0;i<=n;i++)
			for(j=0;j<=n;j++)
				for(q=0;q<=n;q++)
					for(p=0;p<=n;p++){
						if(i==0&&j==0&&q==0&&p==0){b[i][j][q][p]=1;continue;}
						baslen[i][j][q][p]=0;
						cal1(i,j,q,p);
						cal2(i,j,q,p);
						cal3(i,j,q,p);
						cal4(i,j,q,p);
						if(dp[i][j][q][p]==0&&baslen[i][j][q][p]==0)continue;
						b[i][j][q][p]=1;
						ans=max(dp[i][j][q][p],ans);
					}
		printf("%d\n",ans);
	}
	return 0;
}

这段程序的目的是计算将糖果均分给两个人所需的最小操作次数。让我们来分析一下为什么输入47会得到7作为结果。 当输入为47时,程序通过递归调用 `divide(candies, count, minCount)` 进行计算。初始调用是 `divide(47, 0, minCount)`。 首先,程序检查是否只剩下一个糖果。由于47不等于1,所以不满足条件。 接下来,程序检查47是否为偶数。由于47不是偶数,所以执行 `else` 分支。 在 `else` 分支中,程序进行了两个递归调用: 1. `divide(candies + 1, count + 1, minCount)`:这是将糖果数量加1的操作,并将操作次数加1。 2. `divide(candies - 1, count + 1, minCount)`:这是将糖果数量减1的操作,并将操作次数加1。 这两个递归调用会产生分支,并继续递归地进行计算。 对于第一个递归调用 `divide(candies + 1, count + 1, minCount)`,它会将糖果数量从47增加到48,并将操作次数从0增加到1。 接着,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为48。由于48是偶数,程序执行 `divide(candies // 2, count + 1, minCount)`,将糖果数量除以2,并将操作次数加1。 然后,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为24。同样地,程序将糖果数量除以2,并将操作次数加1。 接下来,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为12。同样地,程序将糖果数量除以2,并将操作次数加1。 继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为6。同样地,程序将糖果数量除以2,并将操作次数加1。 接下来,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为3。由于3是奇数,程序将糖果数量加1,并将操作次数加1。 然后,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为4。同样地,程序将糖果数量除以2,并将操作次数加1。 最后,程序继续递归调用 `divide(candies // 2, count + 1, minCount)`,此时糖果数量为2。同样地,程序将糖果数量除以2,并将操作次数加1。 此时,糖果数量变为1,满足终止条件。程序将当前的操作次数1与 `minCount[0]` 中的值进行比较,并将较小值更新到 `minCount[0]` 中。 综上所述,最小操作次数为7。因此,输入47得到的结果是7。 如果你有任何其他问题,请告诉我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值