题目地址:Paths through the Hourglass
这题目好烦好烦好烦!!
因为要算种类数,所以,d[i][j][k]表示从下往上走到(i,j)格子含k数字 有几种方法
#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=a;i<=(int)(b);++i)
#define REPD(i,a,b) for(int i=a;i>=(int)(b);--i)
long long d[50][25][500];
int a[50][25],rest,n;
void DFS1(int i,int j,int w){if(i==n) {rest=w; return;}if(j>1&&d[i+1][j-1][w-a[i][j]]) {printf("L");DFS1(i+1,j-1,w-a[i][j]);}else if(j<=n-i&&d[i+1][j][w-a[i][j]]) {printf("R");DFS1(i+1,j,w-a[i][j]);}
}
void DFS2(int i,int j,int w){if(i==2*n-1) return;if(d[i+1][j][w-a[i][j]]) {printf("L");DFS2(i+1,j,w-a[i][j]);}else if(d[i+1][j+1][w-a[i][j]]) {printf("R");DFS2(i+1,j+1,w-a[i][j]);}
}
int main(int argc, char const *argv[])
{int S;while(scanf("%d%d",&n,&S)==2&&n+S){REP(i,1,n) REP(j,1,n-i+1) scanf("%d",&a[i][j]);REP(i,n+1,n+n-1) REP(j,1,i-n+1) scanf("%d",&a[i][j]);memset(d,0,sizeof(d));REP(i,1,n) d[2*n-1][i][a[2*n-1][i]]=1;REPD(i,2*n-2,n) REP(j,1,i-n+1) {int w=a[i][j];REP(k,w,S) {d[i][j][k]+=d[i+1][j][k-w];d[i][j][k]+=d[i+1][j+1][k-w];}}long long ans=0;REPD(i,n-1,1) REP(j,1,n-i+1) {int w=a[i][j];REP(k,w,S) {if(j>1) d[i][j][k]+=d[i+1][j-1][k-w];if(j<=n-i) d[i][j][k]+=d[i+1][j][k-w];}if(i==1) ans+=d[i][j][S];}printf("%lld\n", ans);REP(i,1,n) if(d[1][i][S]) {printf("%d ", i-1);DFS1(1,i,S); DFS2(n,1,rest);break;}printf("\n");}return 0;
}