sicily1419

来源:互联网 发布:游戏数据分析师是什么? 编辑:程序博客网 时间:2024/06/05 10:06

题目描述:http://soj.me/1419

关于dp的题目,终于把这道纠结了这么久的题目解决掉了。

之前在找状态转移方程的时候,总是没有区分出来,只是简单定义dp(i,j),但是没有标明这个时候人的位置,故需要将人的状态也加进去,故定义dp[2][MAX][MAX],0表示在下面,1表示在上面,然后有里面向外面扩张。

向下面扩张时,有:

dp[0][i][j] = min(dp[0][i+1][j] + (s[i+1]-s[i])*(m-(j-i)),dp[1][i+1][j] + (s[j]-s[i])*(m-(j-i)));

向上面扩张时,有:

dp[1][i][j] = min(dp[0][i][j-1] + (s[j] - s[i])*(m - (j - i)),dp[1][i][j-1] + (s[j] - s[j-1])*(m - (j - i)));

最后结果取min(dp[0][0][m-1],dp[1][0][m-1]);

ps:初始化的时候,需要先讲dp里面的数值定义为最大值。

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;int dp[2][1001][1001];int s[1001];int min(int a,int b){    return a < b ? a : b;}int main(){    int test;    cin >> test;    while(test --)    {        int m,n;        cin >> m >> n;        int i,j;        for(i = 0;i != m;i++)        cin >> s[i];        s[m++] = n;         sort(s,s+m);        int index(0);        memset(dp,0x6f,sizeof(dp));        while(s[index] < n) index ++;        dp[0][index][index] = dp[1][index][index] = 0;        for(i = index;i >= 0;i--)        {            for(j = index;j < m;j++)            {                if(i != index)                {                    dp[0][i][j] = min(dp[0][i+1][j] + (s[i+1]-s[i])*(m-(j-i)),dp[1][i+1][j] + (s[j]-s[i])*(m-(j-i)));                }                if(j != index)                {                    dp[1][i][j] = min(dp[0][i][j-1] + (s[j] - s[i])*(m - (j - i)),dp[1][i][j-1] + (s[j] - s[j-1])*(m - (j - i)));                }            }        }        cout << min(dp[0][0][m-1],dp[1][0][m-1]) << endl;    }    return 0;}