10003-Cutting sticks

You have to cut a wood stick into pieces. The most affordable company, The Analog Cutting Machinery,

Inc. (ACM), charges money according to the length of the stick being cut. Their procedure of work

requires that they only make one cut at a time.

It is easy to notice that different selections in the order of cutting can led to different prices. For

example, consider a stick of length 10 meters that has to be cut at 2, 4 and 7 meters from one end.

There are several choices. One can be cutting rst at 2, then at 4, then at 7. This leads to a price

of 10 + 8 + 6 = 24 because the rst stick was of 10 meters, the resulting of 8 and the last one of 6.

Another choice could be cutting at 4, then at 2, then at 7. This would lead to a price of 10 + 4 + 6 =

20, which is a better price.

Your boss trusts your computer abilities to nd out the minimum cost for cutting a given stick.

Input

The input will consist of several input cases. The rst line of each test case will contain a positive

number

l

that represents the length of the stick to be cut. You can assume

l<

1000. The next line will

contain the number

n

(

n<

50) of cuts to be made.

The next line consists of

n

positive numbers

c

i

(0

<c

i

<l

) representing the places where the cuts

have to be done, given in strictly increasing order.

An input case with

l

= 0 will represent the end of the input.

Output

You have to print the cost of the optimal solution of the cutting problem, that is the minimum cost of

cutting the given stick. Format the output as shown below.

SampleInput

100

3

25 50 75

10

4

4 5 7 8

0

SampleOutput

The minimum cutting is 200.

The minimum cutting is 22.

    结合课上穆老师的讲解时脑中的思路,还有回来后看了“寂静山林”的题解报告后(对于大神对于题目贪心算法可行性讨论的内容不再做出评价和讨论),敲出了自己的代码,并附上此篇  对此题  自己的理解。

“切割木棍”,通过不同的决策,使代价和最小。设k属于( i , j ),并为切割第一刀,则此时问题变为求解( i , k ),( k , j ),加上第一刀切割代价a[j]-a[i]的子问题。则得到状态转移方程:mincost[i][j]=min(mincost[i][j],mincost[i][k]+mincost[k][j]+a[j]-a[i])   则最终通过递归+记忆化求解问题。

注意问题

1、数据的读入

       读入若干组数据,以0为结尾,第一行为l,表示木棍长度,第二行为n表示切割点的个数。第三行为n个数,为n个切割点的位置。

       注意读入格式。用while(scanf("%d",&l)==1 && l)来限定。

2、递归出口的设置

   For循环范围为i+1j-1.则,当i>=j-1时,应直接返回0值。

3、记忆数组bol[][],用来标记计算过的mincost[][],通过记忆化,减少程序的计算量。

#include <cstdio>
#include <cstring>
using namespace std;
int mincost[100][100];
int bol[100][100];
int a[100];
int dp(int i,int j)
{
    int &ans=mincost[i][j],linshi;  //利用引用简化代码 
    if (i>=j-1) return 0;         //递归出口 
    if (bol[i][j]>0) return ans;  //记忆化搜索 
    bol[i][j]=1;
    ans=-1;
    for (int k=i+1;k<=j-1;k++)
      {
      	 linshi=dp(i,k)+dp(k,j)+a[j]-a[i];
      	 if (ans>linshi || ans<0) 
      	   ans=linshi;
      }
    return ans;
      //mincost[i][j]=min(mincost[i][j],mincost[i][k]+min[k][j]+a[j]-a[i])
}
int main()
{
	int l,n;
	while(scanf("%d",&l)==1 && l) 
	{
	  scanf("%d",&n);
      for(int i=1;i<=n;i++) 
	     scanf("%d",&a[i]);  //读入数据
	  memset(mincost,0,sizeof(mincost));
	  memset(bol,0,sizeof(bol)); //初始化数组  
	  a[0]=0;
	  a[n+1]=l;   //设定边界 
	  printf("The minimum cutting is %d.\n",dp(0,n+1));
    }
    return 0;
}


你可能感兴趣的:(10003-Cutting sticks)