UVA - 10003 Cutting Sticks

题目大意:

一个长为L的棍子,有n个切分点,切割费用=被切割时木棍的长度,求最小的切割费用

分析:

区间$dp$。$dp[i][j]=[i,j]$区间的最小切割费用。状态转移方程$dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[j]-a[i]),a[i]$为每个切分点的位置。需要注意的是初始状态$dp[i][i+1]$就已经不能在被分割了所以要重置成$0$,$a[0]=0,a[n+1]=l$表示两个端点。

code:

#define debug
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7;
const int MAXN = 5e3 + 10;
const ll INF = 0x3f3f3f3f;
const ll inf = 0x7fffff;
const ll mod = 1e9 + 7;
const int MOD = 10007;
int a[maxn];
int dp[MAXN][MAXN];
void solve() {
	int l,n;
	while(~scanf("%d",&l)&&l){
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		a[n+1]=l;
		memset(dp,INF,sizeof(dp));
		for(int i=0;i<=n;i++)dp[i][i+1]=0;
		for(int k=2;k<=n+1;k++){
			for(int i=0;i+k<=n+1;i++){
				for(int j=i;j<i+k;j++){
					dp[i][i+k]=min(dp[i][i+k],dp[i][j]+dp[j][i+k]+a[i+k]-a[i]);
				}
			}
		}
		printf("The minimum cutting is %d.\n",dp[0][n+1]);
	}
}
int main(int argc, char const *argv[]) {
//  ios_base::sync_with_stdio(0);
//  cin.tie(0);
//  cout.tie(0);
#ifdef debug
  freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
  int T=1;
//	cin>>T;
  while(T--)
    solve();
  return 0;
}

  

上一篇:UVA 1614 - Hell on the Markets 数学题 非贪心


下一篇:UVA - 10870 Recurrences