HDU 4628 Pieces

狀態DP,以dp[i]表示刪減爲狀態i時所需要的最小次數,dp[i] = min(dp[i],dp[j]+1);其中保證j-i是迴文,因爲要保證j狀態包含i狀態,所以第二重循環式j = (j+1)|i。

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 int64;
typedef long long ll;
#define M 100005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007

int dp[1<<20] , is[1<<20] , len;
char str[20];

bool Judge(int k)
{
	int i , cnt = 0;
	char temp[20];
	for (i = 0 ; i < len ; i++)
	{
		if (k&1)
			temp[cnt++] = str[i];
		k >>= 1;
	}
	for (i = 0 ; i < cnt ; i++)
	{
		if (temp[i] != temp[cnt-1-i])return 0;
	}
	return 1;
}

int main()
{
	int t , i , j;
	scanf("%d",&t);
	while (t--)
	{
		scanf("%s",str);
		len = strlen(str);
		int up = 1<<len;
		memset(is , 0 , sizeof is);
		for (i = 1 ; i < up ; i++)
		{
			if (Judge(i))is[i] = 1;
		}
		memset(dp , max_inf , sizeof dp);
		dp[up-1] = 0;
		for (i = up-1 ; i >= 0 ; i--)
		{
			for (j = i+1 ; j < up ; j = j+1|i)
			{
				if (is[j-i])
					dp[i] = min(dp[i],dp[j]+1);
			}
		}
		printf("%d\n",dp[0]);
	}
	return 0;
}


 

發佈了98 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章