lightoj1191【DP】

    xiaoxiao2021-03-25  61

    0.5s时限,所以就预处理了(好像不预处理也能过,一开始用 cin/cout T掉的。 dp[i][j][k][m] 代表 第 i 个数 是 第 j 个部分 第 k 个 约数条件 m 部分下的答案。 然后切掉 m 这一维,拿ans[i][j][m]记录。 1.产生新部分的首个,为前一部分所有方案和。 dp[i][j][1]=sigma(dp[i-1][j-1][2~min(m,i-1)]); 2.这个部分有 >=2 个的方案 = 这个部分有 k-1 个方案 dp[i][j][ k( 2~min(m,i) ) ] = dp[i][j][k-1];

    #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 55; LL dp[N][N][N]; LL ans[N][N][N]; void init() { for(int m = 1; m <= 50; m++) { dp[1][1][1] = 1; for(int i = 1; i <= 50; i++) { for(int j = 1; j <= min(50,i); j++) { LL temp = dp[i][j][1]; for(int k = 2; k <= min(m,i); k++) { dp[i][j][k] = dp[i-1][j][k-1]; temp += dp[i][j][k]; } dp[i+1][j+1][1] = temp; ans[i][j][m]=temp; } } } } int main() { init(); int T; int cas = 1; scanf("%d",&T); while(T--) { int n,kk,m; scanf("%d%d%d",&n,&kk,&m); printf("Case %d: ",cas++); printf("%lld\n",ans[n][kk][m]); } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-38558.html

    最新回复(0)