标签:
题意:
给你m天,每天在任意的一位坐标轴上出现n个球pos[i][j],0时间的时候在x位置,
从x走向y花费abs(x-y)的价值,拿掉这个球花费cost[i][j]
问你每次时间你都必须走向一个球拿掉它,m天后 最小花费是多少
题解:
设定dp[i][j]表示第i天后在第j个球的最小花费,
容易想到这是一个n*m*n的转移
给了1.5s,值得一试
不过你把转移方程写出来:
对于从当前位置左边转移过来的 dp[i][j] = dp[i-1][k] - pos[i-1][k] + pos[i][j] + cost[i][j];
对于从当前位置右边转移过来的 dp[i][j] = dp[i-1][k] + pos[i-1][k] -pos[i][j] + cos[i][j];
其中dp[i-1][k],pos[i-1][k];都是上一层的,这个我们预处理出就好了啊
即使 dp[i-1][k] - pos[i-1][k] 维护最小 dp[i-1][k] + pos[i-1][k]维护最小,再二分取两者最小就可以了
求个前缀的事。。。。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> using namespace std; const int N = 1e3+20, M = 1e4, mod = 1000000007,inf = 1e9; typedef long long ll; int dp[55][N],cost[55][N],pos[55][N],n,m,x,allpos[N],l[N],r[N]; pair<int,int > P[N]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&m,&n,&x); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&pos[i][j]); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&cost[i][j]); for(int i=1;i<=n;i++) dp[1][i] = abs(x-pos[1][i])+cost[1][i]; for(int j=1;j<=n;j++) P[j] = make_pair(pos[1][j],dp[1][j] - pos[1][j]); sort(P+1,P+n+1); for(int j=1;j<=n;j++) allpos[j] = P[j].first; l[0] = inf; r[n+1] = inf; for(int j=1;j<=n;j++) l[j] = min(l[j-1],P[j].second); for(int j=1;j<=n;j++) P[j] = make_pair(pos[1][j],dp[1][j] + pos[1][j]); sort(P+1,P+n+1); for(int j=n;j>=1;j--) r[j] = min(r[j+1],P[j].second); for(int i=2;i<=m;i++) { for(int j=1;j<=n;j++) { int tmp = upper_bound(allpos+1,allpos+n+1,pos[i][j])- allpos - 1; dp[i][j] = min(l[tmp] + cost[i][j]+pos[i][j],r[tmp+1] + cost[i][j] - pos[i][j]); // cout<<dp[i][j]<<" "; } for(int j=1;j<=n;j++) P[j] = make_pair(pos[i][j],dp[i][j] - pos[i][j]); sort(P+1,P+n+1); for(int j=1;j<=n;j++) allpos[j] = P[j].first; l[0] = inf; r[n+1] = inf; for(int j=1;j<=n;j++) l[j] = min(l[j-1],P[j].second); for(int j=1;j<=n;j++) P[j] = make_pair(pos[i][j],dp[i][j] + pos[i][j]); sort(P+1,P+n+1); for(int j=n;j>=1;j--) r[j] = min(r[j+1],P[j].second); // cout<<endl; } int ans = inf; for(int i=1;i<=n;i++) ans = min(dp[m][i],ans); printf("%d\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zxhl/p/5521847.html