其他分享
首页 > 其他分享> > POJ 2609 DP 双队列DP

POJ 2609 DP 双队列DP

作者:互联网

POJ 2609 DP 双队列DP

题意

思路

\[F_{i, j, k} = 前i个数,左边队列已用j容量,右边队列已用k容量,1代表可行,0代表不可行。 \]

\[ F_{i, j} = F_{i - 1, j} | F_{i - 1, j - a_i} \]

AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

long long aa[1005];
long long su[1005];
bool ff[505][10005] = {{0}};
bool bk[505][10005] = {0};
long long l;

void dfs(int i, int j)
{
	if (!i)
	{
		return;
	}
	if (bk[i][j])
	{
		dfs(i - 1, j - aa[i]);
		printf("port\n");
	}
	else
	{
		dfs(i - 1, j);
		printf("starboard\n");
	}
}

int main()
{
	while (scanf("%lld", &l) == 1)
	{
		memset(ff, 0, sizeof(ff));
		memset(bk, 0, sizeof(bk));
		su[0] = 0;
		l *= 100;
		int cnt = 0;
		while (scanf("%d", &aa[++cnt]) && aa[cnt])
		{
			su[cnt] = aa[cnt] + su[cnt - 1];
		}
		--cnt;
		int cc = 0, co = 0;
		ff[0][0] = 1;
		for (int i = 1; i <= cnt; ++i)
		{
			for (int j = max(aa[i], su[i - 1] - l); j <= l; ++j)
			{
				ff[i][j] |= ff[i - 1][j - aa[i]];
				if (ff[i - 1][j - aa[i]])
				{
					bk[i][j] = true;
					cc = j;
					co = i;
				}
			}
			for (int j = max((long long)0, su[i] - l); j <= l; ++j)
			{
				ff[i][j] |= ff[i - 1][j];
				if (ff[i - 1][j])
				{
					cc = j;
					co = i;
				}
			}
		}
		printf("%d\n", co);
		dfs(co, cc);
	}
	return 0;
}

标签:aa,cnt,int,2609,long,队列,POJ,DP
来源: https://www.cnblogs.com/int-me-X/p/14096028.html