也是经典的计数DP题,想练练手,故意不写记忆化搜索,改成递推,还是成功了嘞。。。不过很遗憾一开始WA了,原来是因为判断结束条件写个 n或s为0,应该要一起为0的,搞的我以为自己递推写挫了,又改了一下,其实递推没问题,就是写出来不好看
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define LL long long using namespace std; const int N=80; LL dp[N][N][1000]; int mat[N][N]; int p[N][N][1000]; int n,s; void print(int d,int loc,int s) { if (d==2*n-1) return; int val=mat[d][loc]; if (d<n){ if (dp[d+1][loc-1][s-val] && loc>1){ putchar(‘L‘); print(d+1,loc-1,s-val); return; } else { putchar(‘R‘); print(d+1,loc,s-val); } } else{ if (dp[d+1][loc][s-val]){ putchar(‘L‘); print(d+1,loc,s-mat[d][loc]); return; } else{ putchar(‘R‘); print(d+1,loc+1,s-mat[d][loc]); } } } int main() { while (scanf("%d%d",&n,&s)!=EOF) { if (n==0 &&s==0) break; memset(mat,0,sizeof mat); for (int i=1;i<=2*n-1;i++){ int k; if (i<=n) k=n-i+1; else k=i-n+1; for (int j=1;j<=k;j++){ scanf("%d",&mat[i][j]); } } memset(dp,0,sizeof dp); for (int i=1;i<=n;i++){ dp[2*n-1][i][mat[2*n-1][i]]=1; } for (int i=2*n-2;i>=1;i--) { int k; if (i>=n) k=i-n+1; else k=n-i+1; if (i>=n){ for (int j=1;j<=k;j++){ for (int q=mat[i][j];q<=s;q++){ dp[i][j][q]+=dp[i+1][j][q-mat[i][j]]; dp[i][j][q]+=dp[i+1][j+1][q-mat[i][j]]; } } } else{ for (int j=1;j<=k;j++){ for (int q=mat[i][j];q<=s;q++){ dp[i][j][q]+=dp[i+1][j][q-mat[i][j]]; dp[i][j][q]+=dp[i+1][j-1][q-mat[i][j]]; } } } } LL ans=0; int loc=-1; for (int i=1;i<=n;i++){ ans+=dp[1][i][s]; if (dp[1][i][s] && loc==-1){ loc=i; } } printf("%lld\n",ans); if (ans>0) { printf("%d ",loc-1); print(1,loc,s); } puts(""); } return 0; }
原文:http://www.cnblogs.com/kkrisen/p/3902760.html