hdu6017 Girls Love 233

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6017

本弱鸡觉得这道题好难,看着别人的代码理解了好久,也没有想的太明白,还是先记录一下把,以后再来看看,

状态分析:

1、剩余没有处理的2

2、上一个2的位置

3、得到233的个数

4、付出的代价

首先要明确的是如果2与2交换或者3与3交换是没有意义的 所以最后2的相对位置是没有变化的,所以我们只需要从后往前处理每一个二就好了

dp[i][j][k]表示剩余i个二没有处理,最后一个2在位置j得到233个数为k的最小花费

状态转移:从后往处理 dp[i-1][t][k+(t+2<j)] = min(dp[i-1][t][k+(t+2<j)] ,dp[i][j][k]+第i-1个2移动到位置t的花费)

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>
#include<vector>

using namespace std;
#define LL long long
int dp[105][105][105]; // 第i个2放在位置j的时候消耗次数k的时候取得的最大233 
void Init(int n)
{
	for(int i = 0;i<n+2;i++)
	{
		for(int j = 0;j<n+2;j++)
		{
			for(int k = 0;k<50;k++)
			{
				dp[i][j][k] = 9999999;
			}
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		char str[105];
		int pos[105];
		int tail = 0;
		scanf("%d%d",&n,&m);
		m/=2;
		Init(n);
		scanf("%s",str+1);
		for(int i = 1;i<=n;i++)
		{
			if(str[i]=='2')
			pos[++tail] = i;
		}
		pos[0] = 0;
		pos[++tail] = n+1;
		
		dp[tail][n+1][0] = 0;
		for(int i = tail;i>1;i--)
		{
			for(int j = n+1;j>=1;j--)
			{
				for(int k = 0;k<n/3+2;k++)
				{
					if(dp[i][j][k]<=m)
					{
						for(int t = j-1;t>=1;t--)
						{
							dp[i-1][t][k+(t+2<j)] = min(dp[i-1][t][k+(t+2<j)],dp[i][j][k]+abs(pos[i-1]-t));
							//cout << i-1 <<dp[i-1][t][k+(t+2<j)] << " " << k+(t+2<j) << endl;
						}
					}
				}
			}
		}
		int ans = 0;

		for(int i = 1;i<=n+1;i++)
		{
			for(int k = 0;k<=n/3+2;k++)
			{
				if(dp[1][i][k]<=m)
				ans = max(k,ans);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值