您的位置:首页 > 其它

TYVJ1061 Mobile Service - DP - 滚动数组

2018-03-28 21:28 295 查看
考虑花费和员工的位置,请求的位置都有关,可以设状态f(i,x,y,z)表示完成了前i个请求,三个员工现在位于x,y,z三处的最小花费,由i可以方便地推到i+1

(DP既可以由i-1推到i,也可以是i推到i+1,灵活应用才能写好方程)

状态转移方程是:

f(i+1,x,y,z)=min(f(i+1,qi+1,y,z),f(i,x,y,z)+c(x,qi+1))f(i+1,x,y,z)=min(f(i+1,qi+1,y,z),f(i,x,y,z)+c(x,qi+1))

f(i+1,x,y,z)=min(f(i+1,x,qi+1,z),f(i,x,y,z)+c(y,qi+1))f(i+1,x,y,z)=min(f(i+1,x,qi+1,z),f(i,x,y,z)+c(y,qi+1))

f(i+1,x,y,z)=min(f(i+1,x,y,qi+1),f(i,x,y,z)+c(z,qi+1))f(i+1,x,y,z)=min(f(i+1,x,y,qi+1),f(i,x,y,z)+c(z,qi+1))

复杂度太高了,不过卡的好的话可以有60分~

但是我们发现员工的位置是根据请求而改变的,所以当第i个请求完成后,一定有一个员工位于位置qiqi,并且是哪个员工位于qiqi对答案是没有影响的

所以我们可以降低一维数组

设f(i,x,y)f(i,x,y)表示完成了前i个请求后,有一个员工位于qiqi处,另外两个员工位于x,y处的最小花费

设q0q0为3,这样就可以从i=0推到i=n

注意一点,对于状态转移方程:f(i+1,x,qi)=min(f(i+1,x,qi),f(i,x,qi)+c(y,qi+1))f(i+1,x,qi)=min(f(i+1,x,qi),f(i,x,qi)+c(y,qi+1))

表示,y位置的员工前往了qi+1qi+1位置,并且x,qi不动,所以i+1处的状态依然是x,qi 而不是 x,qi+1qi+1

但是这样还!不!够!

我们发现内存仍然不够用,需要再优化一维

考虑到第i个阶段只和第i-1阶段有关,我们可以开
f[2][201][201]


设k=0,由k^1来变换k

并且在这样滚动的时候需要想好k和k^1所代表的含义

我设k为下一个请求,k^1为已完成的最后一个请求,那么递推就是由k^1推到k的,并且最终答案也是
min(f[k][x][y])


在取最终答案时不能把f[k]和f[k^1]比较

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 100000 + 10;
int c[210][210],l,n,que[1010],qi=3,ans=0x3f3f3f3f + 200;
int f[2][201][201];
int main() {
scanf("%d %d", &l, &n);
for(int i=1; i<=l; i++)
for(int j=1; j<=l; j++)
scanf("%d", &c[i][j]);
for(int i=1; i<=n; i++)
scanf("%d", que + i);
memset(f,0x3f,sizeof(f));
f[0][1][2] = 0;
int k = 0;
for(int i=0; i<n; i++) {
int x, y;
k^=1;
for(int j=1; j<=l; j++)
for(int t=1; t<=l; t++)
f[k][j][t] = 0x3f3f3f3f;//在统计时要对即将要更新的阶段重新赋最大值
for(int x=1; x<=l; x++)
for(int y=1; y<=l; y++) {
if(x==y || y==x) continue;
f[k][x][y] = min(f[k][x][y],f[k^1][x][y] + c[qi][que[i+1]]);
f[k][qi][y] = min(f[k][qi][y],f[k^1][x][y] + c[x][que[i+1]]);
f[k][x][qi] = min(f[k][x][qi],f[k^1][x][y] + c[y][que[i+1]]);
}
qi = que[i+1];
}
for(int x=1; x<=l; x++)
for(int y=1; y<=l; y++)
ans = min(ans, f[k][x][y]);
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: