UVA - 10564 Paths through the Hourglass
传送门:https://vjudge.net/problem/UVA-10564
题目大意:给你一张形如沙漏一般的图,每一个格子有一个权值,问你有多少种方案可以从第一行走到最后一行,并且输出起点最靠前的方案,以及此方案的起点编号,起点相同则字典序最小。
题解:
很容易想到一个DP,dp[i][j][S]代表到第i层,第j列,从第一层到这里的路径和为S的方案数,最后只要查询最后一行的方案数即可了。但是这样很不好输出方案!我们可能需要从终点向上dfs,但是又无法保证起点编号最小以及字典序最小。但是我们能从终点向上dfs,那么如果我们反过来DP呢?可行啊,这样就可以从起点向终点dfs了,贪心选择可行的路径即可。
需要注意的是上下两个一半的沙漏的转移一个是到j与j+1,一个是j与j-1,要考虑清楚细节!
1 #include<queue> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 #define RG register 8 #define LL long long 9 #define fre(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); 10 using namespace std; 11 const int MAXN=22,MAXS=599; 12 int n; 13 LL ans,S; 14 LL a[MAXN*2][MAXN],dp[MAXN*2][MAXN][MAXS]; 15 void dfs(int x,int y,int sum); 16 int main() 17 { 18 while(scanf("%d%lld",&n,&S)!=EOF) 19 { 20 if(n+S==0)break; 21 for(int i=1;i<=n;i++) for(int j=1;j<=n-i+1;j++) scanf("%lld",&a[i][j]); 22 for(int i=n+1;i<2*n;i++) for(int j=1;j<=i-n+1;j++) scanf("%lld",&a[i][j]); 23 memset(dp,0,sizeof dp); 24 for(int i=1;i<=n;i++) dp[n*2-1][i][a[n*2-1][i]]=1; 25 for(int i=n*2-2;i>=n;i--) 26 for(int j=1;j<=i-n+1;j++) 27 for(int k=0;k<=S;k++) 28 { 29 if(dp[i+1][j][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j][k]; 30 if(dp[i+1][j+1][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j+1][k]; 31 } 32 for(int i=n-1;i>=1;i--) 33 for(int j=1;j<=n-i+1;j++) 34 for(int k=0;k<=S;k++) 35 { 36 if(dp[i+1][j][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j][k]; 37 if(dp[i+1][j-1][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j-1][k]; 38 } 39 ans=0; for(int i=1;i<=n;i++) ans+=dp[1][i][S]; printf("%lld\n",ans); 40 for(int i=1;i<=n;i++) 41 if(dp[1][i][S]) 42 { 43 printf("%d ",i-1); 44 int x=1,y=i,sum=S; 45 while(x<n*2-1) 46 { 47 if(x<n) 48 { 49 if(dp[x+1][y-1][sum-a[x][y]]) sum-=a[x][y],y--,printf("L"); 50 else sum-=a[x][y],printf("R"); 51 } 52 else 53 { 54 if(dp[x+1][y][sum-a[x][y]]) sum-=a[x][y],printf("L"); 55 else sum-=a[x][y],y++,printf("R"); 56 } 57 x++; 58 } 59 break; 60 } 61 printf("\n"); 62 } 63 return 0; 64 }