10003 - Cutting Sticks

描述:题目难度为 2,将一条长为n的木棍切成m+1块,但是切割顺序不同,寻找状态方程s[x][y]=min(s[x][y],s[x][i]+s[i][y]+s[y]-s[x]);然后就可以敲代码了

代码一(递归,耗时较多):

#include <cstdio>

#include <cstring>

int num[55],s[55][55];

int min(int a,int b)

{

    if(a>b) return b;

    else return a;

}

int dp(int x,int y)

{

    if(y-x==1) return 0;

    if(s[x][y]>0) return s[x][y];

    s[x][y]=1000000;

    for(int k=x+1; k<y; k++) s[x][y]=min(s[x][y],dp(x,k)+dp(k,y)+num[y]-num[x]);

    return s[x][y];

}

int main()

{

   // freopen("a.txt","r",stdin);

    int n,m;

    while(scanf("%d",&n)!=EOF)

    {

        if(!n) break;

        memset(s,0,sizeof(s));

        scanf("%d",&m);

        num[m+1]=n;

        for(int i=1; i<=m; i++) scanf("%d",&num[i]);

        printf("The minimum cutting is %d.\n",dp(0,m+1));

    }

    return 0;

}

 

代码二(耗时少):

#include <cstdio>

#include <cstring>

int num[55],s[55][55];

int min(int a,int b)

{

    if(a>b) return b;

    else return a;

}

int main()

{

   // freopen("a.txt","r",stdin);

    int n,m;

    while(scanf("%d",&n)!=EOF)

    {

        if(!n) break;

        memset(s,0,sizeof(s));

        scanf("%d",&m);

        num[m+1]=n;

        for(int i=1; i<=m; i++) scanf("%d",&num[i]);

        int k=2,x=0;

        for( ; x+k<=m+1&&k<=m+1; x++)

        {

            int y=x+k;

            if(!s[x][y]) s[x][y]=1000000;

            for(int i=x+1; i<=y; i++) s[x][y]=min(s[x][y],s[x][i]+s[i][y]+num[y]-num[x]);

            if(y==m+1&&!x) break;

            if(x+k==m+1)

            {

                x=-1;

                k++;

            }

        }

        printf("The minimum cutting is %d.\n",s[0][m+1]);

    }

    return 0;

}


你可能感兴趣的:(cut)