HDU 1565 方格取数(1) HDU 2167 Pebbles 基础状态压缩动态规划

两个题目都是一样的套路..开始学习状压DP,记录一下 。

先预处理状态,找到可行的所有状态,然后遍历所有可能性。

先找单行所有可行状态,然后在进行运算的时候判断是否与上一行冲突,不冲突说明是一种方案,记录一下。

附上HDU2167代码:

#include<stdio.h>
#include<string.h>
#define M 1<<16
int a[20][20],dp[20][20000];
int s[20000];

void  inti()//记录单行所有可取状态
{
	int k=0,i;
	for(i=0;i<M;i++)
	{
		if(i&(i<<1))
			continue;
		s[k++]=i;
	}
}
int getsum(int i,int x)//某种状态所取得的和
{
	int sum=0,t=0;
	while(x)//末位是1就加上
	{
		if(x&1)
			sum+=a[i][t];
		t++;
		x>>=1;
	}
	return sum;
}

int main()
{
	char ch[10005];
	int r=0,c=0;
	int i,j,k;
	inti();
	while(gets(ch))
	{
		if(strcmp(ch,"")!=0)
		{
			int num=0;
			for(i=0;ch[i]!='\0';i++)
			{
				if(ch[i]==' ')
				{
					a[r][c++]=num;
					num=0;
				}
				else
					num=num*10+ch[i]-'0';
			}
			a[r][c]=num;
			r++;c=0;
		}
		else
		{
			int x=1<<r;
			for(i=0;s[i]<x;i++)
				dp[0][i]=getsum(0,s[i]);
			for(i=1;i<r;i++)
			{
				for(j=0;s[j]<x;j++)
				{
					int max=0;
					dp[i][j]=getsum(i,s[j]);
					for(k=0;s[k]<x;k++)
					{
						if(s[j]&s[k]||s[j]&s[k]<<1||s[j]<<1&s[k])//相邻对角线也不能取...
							continue;
						if(dp[i-1][k]>max)
							max=dp[i-1][k];
					}
					dp[i][j]+=max;
				}
			}
			int ans=0;
			for(i=0;s[i]<x;i++)
			{
				if(dp[r-1][i]>ans)
					ans=dp[r-1][i];
			}
			printf("%d\n",ans);
			memset(a,0,sizeof(a));
			memset(dp,0,sizeof(dp));
			r=0;c=0;
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值