hdu2167 状态压缩DP入门题

照猫画虎写了道入门题。。讲道理这东西我不应该现在才来学TAT

//状态压缩DP入门题
//九宫格的相邻限制条件
//N*N 3<=N<=15
/*
dp[i][j]表示前i行,最后一行状态为j时得到的最大分数和
对于一行j的所有可能可以用DFS弄出来,在同行搜索的时候只要保证行不相邻。
在判断合法状态转移的时候,判断本身、左移和右移即可。
dp[i][j] = max{dp[i-1][k] + sum[i][j]},其中k为和j不冲突的状态。
s[0]表示状态总数,s[i]表示第i个状态。
sum[i][j]表示第i行第j个状态的和
*/
#include <bits/stdc++.h>
using namespace std;
char str[100];
int n,len,ans;
int a[20][20], sum[20][40000];
int dp[20][40000];
int s[40000];
void dfs(int x, int last, int now)//last表示上一个格子有没有放,now表示当前状态
{
	if (x > n)
	{
		s[++s[0]] = now;
		return ;
	}
	dfs(x+1, 0, now << 1);
	if (!last)
		dfs(x+1, 1, now << 1 | 1);
}
int main()
{
	int i1 = 0;
	while (gets(str))
	{
		i1++;
		len = strlen(str);
		if (len)
		{
			n = (len + 1) / 3;
			for (int j=0;j<n;j++)
				a[i1][j+1] = (str[3*j] - 48) * 10 + (str[3*j+1] - 48);
		}
		else 
		{
			i1 = 0;
			s[0] = 0;
			dfs(1,0,0);
			for (int i=1;i<=n;i++)
				for (int j=1;j<=s[0];j++)
				{
					sum[i][j] = dp[i][j] = 0;
					for (int k = 1;k<=n;k++)
						if ((s[j] & (1<<(n-k))) != 0)
						{
							sum[i][j] += a[i][k];
						}

					for (int k = 1;k<=s[0];k++)
					{
						if ((s[j] & s[k]) == 0 && (s[j] & (s[k] << 1)) == 0 && (s[j] & (s[k] >> 1)) == 0)
						{
							dp[i][j] = max(dp[i][j], dp[i-1][k] + sum[i][j]);
						}
					}
				}
			ans = 0;
		    for (int i=1;i<=s[0];i++)
		    	ans = max(ans, dp[n][i]);
		    printf("%d\n", ans);
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值