ZOJ 3675 Trim the Nails

本文探讨了如何通过状态压缩技术解决TrimtheNails问题,详细解释了问题背景、解题思路以及更新后的代码实现。文章深入浅出地介绍了如何利用二进制串进行状态转移,以达到剪光指甲的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

J题:Trim the Nails

题目大意:
  给一把可能有缺口宽度为n的刀(输入.表示是缺口,*表示正常),
  用这把刀去剪宽度为m的指甲,刀可以顺用也可以反用,求至少要
  用这把剪刀剪多少次才能把指甲剪光;

 

解题思路:(状态压缩)
 
   开始把没剪的时候的指甲看成一连串二进制1串,剪刀一部分后,一部分1串
   就变成了0串,当指甲剪光的时候,所有的1串就变成了0串,用数字表示就是
   0,我们把剪刀也看成是连续的一串二进制串,输入是*时,二进制位为0,当
   输入是.时,二进制位为1,操作就是:指甲的二进制串和剪刀的二进制串位与来
   来进行状态转移,转移的时候取最小值,每个状态,剪刀总共平移n次来进行
   这样的操作,最后的答案就是状态0的值;
  
更新代码如下:

*/

#include<stdio.h>
#include<string.h>
int dp[1<<20],op1,op2;
char str[15];
inline int Min(int a,int b){return a<b?a:b;}
inline int Max(int a,int b){return a<b?b:a;}
int main()
{
	int n,m,i,len,j;
	while(scanf("%d",&n)!=EOF)
	{
		scanf("%s",str);
		op1=op2=(1<<30)-1;
		for(i=0;i<n;i++) 
		{
			if(str[i]=='*')
			{
				op1&=~(1<<i);
				op2&=~(1<<(n-i-1));
			}
		}
		scanf("%d",&m);
		if(op1==(1<<30)-1){printf("-1\n");continue;}
		len=(1<<m)-1;
		memset(dp,127,sizeof(dp));
		dp[len-1]=0;
		int p1,p2,p3,p4,l,v;
		l=Max(n,m);
		for(i=len;i>0;i--)
		{
			p1=op1;p2=op2,p3=op1,p4=op2;
			v=dp[i]+1;
			if(dp[i]<2139062143)
			{
				for(j=0;j<l;j++)
				{
					dp[(i&p1)]=Min(dp[(i&p1)],v);
					dp[(i&p2)]=Min(dp[(i&p2)],v);
					dp[(i&p3)]=Min(dp[(i&p3)],v);
					dp[(i&p4)]=Min(dp[(i&p4)],v);
					p1=(p1<<1)|1;
					p2=(p2<<1)|1;
					p3=(p3>>1)|(1<<29);
					p4=(p4>>1)|(1<<29);
				}
			}
		}
		printf("%d\n",dp[0]);
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值