UVA10564

  1 /*
  2 题意:
  3 输入N,S,沙漏型的 2*N-1行数据,问从上走到下和为 S 的方法有多少种,
  4 每个格子只能走到它下面相邻的两个格子 。 
  5 第一行输出多少种方式 ,第二行输出 起点下标 与 路径 。
  6 
  7 还是看了题解之后才造怎么写,鲜有不看就会的啊= =,还需努力! 
  8 dp[i][j][k] 表示走到 (i,j)时和为 K 的方法有多少种。
  9 从下面走到上面,好确定起点。 
 10 用一个数组记录方向,0->L, 1->R 
 11  
 12 */
 13 
 14 
 15 #include<cstdio>
 16 #include<cstring>
 17 #include<algorithm>
 18 #define ll long long
 19 using namespace std;
 20 const int maxn=50;
 21 ll dp[maxn][maxn][550];
 22 bool dir[maxn][maxn][550][2];
 23 int a[maxn][maxn];
 24 int main()
 25 {
 26     int n,s;
 27     while(scanf("%d%d",&n,&s)!=EOF)
 28     {
 29         if(!n && !s) return 0;
 30         for(int i=1;i<=n;i++)        
 31             for(int j=1;j<=n-i+1;j++)
 32                 scanf("%d",&a[i][j]);
 33         for(int i=n+1;i<=n*2-1;i++)
 34             for(int j=1;j<=i-n+1;j++)
 35                 scanf("%d",&a[i][j]);
 36                 
 37         memset(dp,0,sizeof(dp));
 38         memset(dir,false,sizeof(dir));
 39         
 40         for(int i=1;i<=n;i++)
 41         {
 42             int    h=s-a[2*n-1][i];
 43             dp[2*n-1][i][h]=1;
 44         }
 45         for(int i=2*n-2;i>=n;i--)
 46         {
 47             for(int j=1;j<=i-n+1;j++)
 48             {
 49                 for(int k=0;k<=s;k++)
 50                 {
 51                     int h=k+a[i][j];
 52                     if(dp[i+1][j][h]!=0)
 53                     {
 54                         dp[i][j][k] += dp[i+1][j][h];
 55                         dir[i][j][k][0]=true;
 56                     }
 57                     if(dp[i+1][j+1][h]!=0)
 58                     {
 59                         dp[i][j][k] += dp[i+1][j+1][h];
 60                         dir[i][j][k][1]=true;
 61                     }                    
 62                 }
 63             }
 64         }
 65         for(int i=n-1;i>=1;i--)
 66         {
 67             for(int j=1;j<=n-i+1;j++)
 68             {
 69                 for(int k=0;k<=s;k++)
 70                 {
 71                     int h = k + a[i][j] ;
 72                     if(dp[i+1][j-1][h]!=0)
 73                     {
 74                         dp[i][j][k] += dp[i+1][j-1][h];
 75                         dir[i][j][k][0]=true;                        
 76                     }
 77                     if(dp[i+1][j][h]!=0)
 78                     {
 79                         dp[i][j][k] += dp[i+1][j][h];
 80                         dir[i][j][k][1]=true;
 81                     }
 82                 }                
 83             }
 84         }
 85         int ansi=-1;
 86         ll ans=0;
 87         for(int i=1;i<=n;i++)
 88         {
 89             if(dp[1][i][0] != 0 && ansi ==-1)
 90                 ansi=i;
 91             ans+=dp[1][i][0];
 92         }
 93         printf("%lld
",ans);            
 94         if(ans==0)
 95         {
 96             printf("
");     
 97             continue;
 98         }
 99         printf("%d ",ansi-1);
100         int j=ansi;
101         ll cur=0;
102         for(int i=1;i<=n*2-1;i++)
103         {
104             int pos=j;
105             if(dir[i][pos][cur][0] )
106             {
107                 printf("L");
108                 if(i<n) j--;
109             }
110             else if(dir[i][pos][cur][1] ) 
111             {
112                 printf("R");
113                 if(i>=n) j++;
114             }
115             cur += a[i][pos];
116         }
117         printf("
");
118     }
119     return 0;
120 }
原文地址:https://www.cnblogs.com/ember/p/4915561.html