UVA - 1336 Fixing the Great Wall 记忆化搜索

题目链接:UVA - 1336

最近心情炒鸡差 = = 不过么 也没什么 总会过去的 该做的还是要做的 恩。。教主说的挺对的还是要少看题解多思考。。觉得CF的题目都蛮锻炼脑子的准备刷lrj刷不动的时候做几道那个。

这是调了两天调出来的DP。。。说起来也不算很难吧,毕竟书上有解析,大意就是有个机器人在x点,移动速度v,有n个地方需要修补,给出这些点的位置,立即修补的花费c,以及每过一秒(我忘了是啥了,反正是一个单位时间),所增加的花费d,即修补某点i所需要的花费为d*abs(x[i]-x)/v+c,所以先按x对所需要修补的点进行排序,然后预处理求出前n个点的d的总和,时间每增加一个单位,总花费必然增加d[当前未修补的点集]*1,然后找到机器人所在的位置(某两点之间),从那两个位置开始求解即可。注意有可能机器人在最左边或最右边,所以应当注意遍历时数组的范围,另外后来几次错是因为循环中的小于等于写成了小于,导致只有一个点时无法求得正确结果。

#include 
#include 
#include 
#include 
#include 
#include 
#define INF 0x7f7f7f7f
using namespace std;
const int maxn = 1024;
struct Pos{
    double x,c,d;
    Pos(double a=0,double b=0,double cc=0):x(a),c(b),d(cc){}
    bool operator < (const Pos& p)const {return x0) return dp[x][y][pos];
    double temp = INF;
    //cout<<"***test here***"<1){
        if(pos==0)//求区间的d值之和时是 1 - x-1,y - n 
            temp=min(temp,solve(x-1,y,0)+fabs(p[x].x-p[x-1].x)/v*(res[x-1]+res[n]-res[y])+p[x-1].c);
        else
            temp=min(temp,solve(x-1,y,0)+fabs(p[y].x-p[x-1].x)/v*(res[x-1]+res[n]-res[y])+p[x-1].c);
    }
    if(y=x){
                if(i>=1)//等于
                    ans=min(ans,solve(i,i,0)+fabs(p[i].x-x)/v*res[n]+p[i].c);
                if(i<=n)
                    ans=min(ans,solve(i+1,i+1,1)+fabs(p[i+1].x-x)/v*res[n]+p[i+1].c);
                break;
            }
        }
        printf("%d\n",int(ans));
    }
    return 0;
}
希望所有像我一样在DP中挣扎的人们在不久后的某天就能将DP运用自如,加油!

你可能感兴趣的:(UVA)