uva 10564 - Paths through the Hourglass

dp[i][j][k]代表从(i,j)出发,到达最底层的权值之和为k的路径条数

剩下的就比较容易了

#include <iostream>

#include<cstdio>

#include<cstring>

using namespace std;

typedef long long ll;

int n,s,N;

int tree[50][50],L[50][50],R[50][50];

ll dp[50][50][505];

char ans[50];

bool ok(int i,int j)

{

    return j>0&&j<=tree[i][0];

}

ll DP(int i,int j,int s)

{



    if(dp[i][j][s]!=-1)

    return dp[i][j][s];

    dp[i][j][s]=0;

    //'L'

    int x=i+1,y=L[i][j];

    if(ok(x,y))

    dp[i][j][s]+=DP(x,y,s-tree[i][j]);



    //'R'

    x=i+1,y=R[i][j];

    if(ok(x,y))

    dp[i][j][s]+=DP(x,y,s-tree[i][j]);



    return dp[i][j][s];

}

void print(int i,int j,int s)

{



    if(i==N-1)

    return ;

    //'L'

    int x=i+1,y=L[i][j];

    bool OK=false;

    if(ok(x,y)&&dp[x][y][s-tree[i][j]]>0)

    {

        OK=true;

        ans[i]='L';

        print(x,y,s-tree[i][j]);

    }



    //'R'

    x=i+1,y=R[i][j];

    if(!OK&&ok(x,y)&&dp[x][y][s-tree[i][j]]>0)

    {

        ans[i]='R';

        print(x,y,s-tree[i][j]);

    }

}

int main()

{

    while(scanf("%d%d",&n,&s),n+s)

    {

        for(int i=0;i<n;i++)

        {

            //这一行数的个数

            tree[i][0]=n-i;

            for(int j=1;j<=tree[i][0];j++)

            {

                L[i][j]=j-1;    R[i][j]=j;

                scanf("%d",&tree[i][j]);

            }

        }

        L[n-1][1]=1;R[n-1][1]=2;



        for(int i=n;i<n*2-1;i++)

        {

            tree[i][0]=2+i-n;

            for(int j=1;j<=tree[i][0];j++)

            {

                L[i][j]=j;  R[i][j]=j+1;

                scanf("%d",&tree[i][j]);

            }

        }

        N=2*n-1;

        memset(dp,-1,sizeof(dp));

        for(int j=1;j<=tree[N-1][0];j++)

        {

            for(int k=0;k<=s;k++)

            dp[N-1][j][k]=(k==tree[N-1][j])?1:0;

        }

        int start=-1;

        ll total=0;

        for(int i=1;i<=tree[0][0];i++)

        {

            total+=DP(0,i,s);

            if(start==-1&&dp[0][i][s]>0)

            {

                start=i;

                print(0,i,s);

            }

        }

        ans[N-1]=0;

        printf("%lld\n",total);

        if(total)

        printf("%d %s\n",start-1,ans);

        else

        puts("");

    }

    return 0;

}

  

你可能感兴趣的:(Path)