题意: 有一根长度为L的木棍,木棍上面有n个切割点,每一次切割都要付出当前木棍长度的代价,问切割的最小代价
dp[le][ri] 表示区间为[le,ri]的子问题最优解
/*
uva 10003
记忆化搜索
0.690s
*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxL= 1000 ;
int L,n;
int dp[maxL+5][maxL+5];
int a[55];
int DP(int le,int ri)
{
if(~dp[le][ri]) return dp[le][ri];
int & ans =dp[le][ri];
ans=INF;
for(int x=le+1;x<ri;x++)
{
ans=min(ans,a[ri]-a[le]+DP(le,x)+DP(x,ri) );
}
if(ans==INF) ans=0;
return ans;
}
int main()
{
while(~scanf("%d",&L)&&L)
{
scanf("%d",&n);
for1(i,n)
{
scanf("%d",&a[i]);
}
a[0]=0;a[n+1]=L;
memset(dp,-1,sizeof dp);
printf("The minimum cutting is %d.\n",DP(0,n+1));
}
return 0;
}
/*
uva 10003
递推
0.020s
*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxL= 1000 ;
int L,n;
int dp[maxL+5][maxL+5];
int a[55];
int main()
{
while(~scanf("%d",&L)&&L)
{
scanf("%d",&n);
for1(i,n)
{
scanf("%d",&a[i]);
}
a[0]=0;a[n+1]=L;//添加两个点,代表木棍的左右端点。
for(int i=0;i<=n;i++)//边界
{
dp[i][i+1]=0;
}
for(int add=2;add<=n+1;add++)//枚举区间长度
{
for(int le=0;le+add<=n+1;le++)//枚举区间左端点
{
int ri=le+add;//求出区间右端点
dp[le][ri]=INF;
for(int k=le+1;k<ri;k++)//枚举该区间第一次划分的点
{
dp[le][ri]=min(dp[le][ri],a[ri]-a[le]+dp[le][k]+dp[k][ri]);
}
}
}
printf("The minimum cutting is %d.\n",dp[0][n+1]);
}
return 0;
}
/*
uva 10003
四边形优化
0.020s
*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxL= 1000 ;
int L,n;
int dp[maxL+5][maxL+5];
int a[55];
int best[maxL+5][maxL+5];
int main()
{
while(~scanf("%d",&L)&&L)
{
scanf("%d",&n);
for1(i,n)
{
scanf("%d",&a[i]);
}
a[0]=0;a[n+1]=L;//添加两个点,代表木棍的左右端点。
for(int i=0;i<=n;i++)//边界
{
dp[i][i+1]=0;
}
for(int add=2;add<=n+1;add++)//枚举区间长度
{
for(int le=0;le+add<=n+1;le++)//枚举区间左端点
{
int ri=le+add;//求出区间右端点
if(add==2)
{
dp[le][ri]=a[ri]-a[le];
best[le][ri]=le+1;
continue;
}
dp[le][ri]=INF;
for(int k=best[le][ri-1];k<=best[le+1][ri];k++)//四边形优化
{
int ret=a[ri]-a[le]+dp[le][k]+dp[k][ri];
if(ret<dp[le][ri])
{
dp[le][ri]=ret;
best[le][ri]=k;
}
}
}
}
printf("The minimum cutting is %d.\n",dp[0][n+1]);
}
return 0;
}