您的位置:首页 > 其它

poj3003&2397 DP 记录路径

2012-03-02 11:01 204 查看
这两题是一模一样的

最近做了好多这种背包的题,但是这题需弄清的地方还是不少,有些绕

f[][]数组其实是可以省的

#include <iostream>
#define oo 10000000
using namespace std;
int cas,n,a[1010],p,q,dp[2][1010],pre[41][1010];
bool f[2][1010],ans[41];
int main() {
scanf("%d",&cas);
while (cas--) {
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=0;i<1010;i++)
dp[0][i] = 0;
memset(f[0],0,sizeof(f[0]));
f[0][0] = true;
p = 1;
q = 0;
for (int i=1;i<=n;i++) {
memset(f[p],0,sizeof(f[p]));
for (int j=0;j<1010;j++)
dp[p][j] = 0;
for (int j=0;j<1010;j++)
if (f[q][j]) {
if (j+a[i]<1010) {
if (!f[p][j+a[i]])  {
dp[p][j+a[i]] = max(j+a[i],dp[q][j]);
f[p][j+a[i]] = true;
pre[i][j+a[i]] = j;
}
else if (dp[p][j+a[i]]>max(j+a[i],dp[q][j])) {
dp[p][j+a[i]] = max(j+a[i],dp[q][j]);
pre[i][j+a[i]] = j;
}
}
if (j-a[i]>=0) {
if (!f[p][j-a[i]])  {
dp[p][j-a[i]] = max(j-a[i],dp[q][j]);
f[p][j-a[i]] = true;
pre[i][j-a[i]] = j;
}
else if (dp[p][j-a[i]]>max(j-a[i],dp[q][j])) {
dp[p][j-a[i]] = max(j-a[i],dp[q][j]);
pre[i][j-a[i]] = j;
}
}
}
p = 1 - p;
q = 1 - q;
}
if (dp[q][0]==0) printf("IMPOSSIBLE\n");
else  {
memset(ans,0,sizeof(ans));
int i = n, h = 0;
while (i!=1) {
ans[i] = (pre[i][h]>h);
h = pre[i][h];
i--;
}
for (int i=1;i<=n;i++)
if (!ans[i]) printf("U");
else printf("D");
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: