POJ1036 Gangsters DP

题意:一群匪徒要进入一个酒店。酒店的门有k+1个状态,每个匪徒的参数是:进入时间,符合的状态,携带的钱。

酒店的门刚开始状态0,问最多这个酒店能得到的钱数。

思路:

dp数组为DP[T][K].

转移方程dp[i][j]=max(dp[i-1][j],dp[i-1][j-1],dp[i-1][j+1])

因为转移i只跟i-1有关,所以可以用滚动数组dp[2][k].

其实这道题的转移方程很容易想到,只是编程的时候处理边界等细节比较麻烦。


#include<iostream>
#include<algorithm>
#define max(a,b) (a>b?a:b)
using namespace std;
const int N=105,K=105,T=30005;
int dp[2][K];
struct GAN
{
	int t,p,s;
}gan[N];
bool cmp(const GAN &a,const GAN &b)
{
	return a.t<b.t;
}
int n,k,t;
bool Hash[T];
void solve()
{
	for(int i=1;i<=n;i++)
		Hash[gan[i].t]=true;
	int w;
	sort(gan+1,gan+n+1,cmp);
	for(int i=1;i<=t;i++)
	{
		
		for(int j=0;j<=k&&j<=i;j++)//注意j<=i
		{
			w=0;
			if(Hash[i])
			{
				for(int ii=1;ii<=n;ii++)
				{
					if(gan[ii].t==i&&gan[ii].s==j)
						w+=gan[ii].p;
				}
			}
			if(j==k)
				dp[i%2][j]=max(dp[(i-1)%2][j-1],dp[(i-1)%2][j]);
			else if(j==0)
				dp[i%2][j]=max(dp[(i-1)%2][j+1],dp[(i-1)%2][j]);
			else
				dp[i%2][j]=max(dp[(i-1)%2][j-1],max(dp[(i-1)%2][j+1],dp[(i-1)%2][j]));
			dp[i%2][j]+=w;
		}
	}
	int ans=0;
	for(int i=0;i<=k;i++)
	{
		ans=max(ans,dp[t%2][i]);
	}
	printf("%d\n",ans);
}
int main()
{
	scanf("%d%d%d",&n,&k,&t);
	for(int j=1;j<=n;j++)
	{
		scanf("%d",&gan[j].t);
	}
	for(int j=1;j<=n;j++)
	{
		scanf("%d",&gan[j].p);
	}
	for(int j=1;j<=n;j++)
	{
		scanf("%d",&gan[j].s);
	}
	solve();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值