UVA 10261 Ferry Loading


// [题意]
// n辆车按顺序安排在一个渡口的左边或右边,不超过渡口长度最多放多少辆
// 相当于n个物品按顺序尽量多地放在两个相同容量的背包里
// 如果放不下后面的就不放了,题目还要求输出要放的车都放哪边?记录路径即可
// 由于是按顺序放,所以第i辆车放的话,i前面的车必然已经放好了,不可能不放

// [解题方法]
// dp[i][j]=1 表示左边车占了j长度时,可以放i辆车
// 设前i辆车总长度为sum[i],则:
// 对于dp[i][j]左边占了j长度,右边就必然占了sum[i]-j的长度了
// dp[i][j]=0 表示这种状态不可行
// 设V为公路长度,w[i]为第i辆车的长度,状态转移如下:(0<=j<=V)
// dp[i][j] = (j>=w[i]&&dp[i-1][j-w[i]]) || (sum[i]-j<=V&&dp[i-1][j])
// 放左边 放右边

#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define N 2005
#define M 10005
#define inf 0x3fffffff

int dp[N][M], w[N], sum[N];
int pre[N][M], ans[N];

int main()
{
int t, i, j, k, V, n, vj;
cin >> t;
while (t--)
{
cin >> V;
V *= 100;
memset (dp, 0, sizeof(dp));
dp[0][0] = 1;
n = 0;
sum[0] = 0;
while(cin >> k, k)
{
++n;
w[n] = k;
sum[n] = sum[n-1] + k;
}
vj = -1;
for (i = 1; i <= n; i++)
{
for (j = 0; j <= V; j++)
{
if (j >= w[i] && dp[i-1][j-w[i]]) {
k = i;
vj = j;
dp[i][j] = 1;
pre[i][j] = j-w[i];
} else if (sum[i]-j <= V && dp[i-1][j]) {
k = i; //更新最大能放的车辆数
vj = j;
dp[i][j] = 1;
pre[i][j] = j; //记录路径
}
}
}
i = k;
while (i--)
{
j = pre[i+1][vj];
if (j == vj) ans[i] = 1;
else ans[i] = 0;
vj = j;
}
cout << k << endl;
for (i = 0; i < k; i++)
{
if (ans[i]) puts ("starboard");
else puts ("port");
}
if (t) puts("");
}
return 0;
}

你可能感兴趣的:(动态规划,C++,ACM,编程,算法,KIDx)