题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=12&problem=944&mosmsg=Submission+received+with+ID+17137424
思路:比较裸的区间DP吧,状态转移方程为dp[i][j]=min(dp[i][k]+dp[k][j])+a[j]-a[i],可以用四边形不等式进行优化
AC代码1:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
const int inf = 0x3f3f3f3f;//1061109567
typedef long long LL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int a[55],dp[55][55];
int main()
{
int l;
while(scanf("%d",&l) && l)
{
memset(dp,inf,sizeof(dp));
int n;
scanf("%d",&n);
a[0] = 0;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
a[n+1] = l;
for(int i=0; i<=n; i++)
{
dp[i][i+1] = 0;
}
for(int r=3; r<=n+2; r++)//注意这里的长度是n+2
{
for(int i=0; i<=n-r+2; i++)//注意这里i的取值范围
{
int j = i + r - 1;
for(int k=i+1; k<j; k++)
{
if(dp[i][j] > dp[i][k] + dp[k][j])
dp[i][j] = dp[i][k] + dp[k][j];
}
dp[i][j] += a[j] - a[i];
//printf("%d %d %d\n",i,j,dp[i][j]);
}
}
printf("The minimum cutting is %d.\n",dp[0][n+1]);
}
return 0;
}
AC代码2:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
const int inf = 0x3f3f3f3f;//1061109567
typedef long long LL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int a[55],dp[55][55];
int main()
{
int l;
while(scanf("%d",&l) && l)
{
memset(dp,inf,sizeof(dp));
int n;
scanf("%d",&n);
a[0] = 0;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
a[n+1] = l;
for(int i=0; i<=n; i++)
{
dp[i][i+1] = 0;
}
for(int r=3; r<=n+2; r++)
{
for(int i=0; i<=n-r+3; i++)//比上一个多算了一次,其实是没有必要的
{
int j = i + r - 1;
for(int k=i+1; k<j; k++)
{
if(dp[i][j] > dp[i][k] + dp[k][j])
dp[i][j] = dp[i][k] + dp[k][j];
}
dp[i][j] += a[j] - a[i];
}
}
printf("The minimum cutting is %d.\n",dp[0][n+1]);//注意这里是dp[0][n+1]
}
return 0;
}