UVA 10912 Simple Minded Hashing

来源:互联网 发布:java rmi漏洞解决 编辑:程序博客网 时间:2024/06/06 03:57

大意:给定一个字符长度及权值,让你求组成该权值的字符的全部排列,字符串严格遵循上升序列。

思路:设d[i][j][s]表示当前字符为i时,剩余长度为j,组成的权值为s的可能情况,由于遵循严格的上升序列,事实上,初始化只需写一遍即可。因为设长度为L’的集合为S‘,长度为L的集合为L,若L' < L,由于遵循该字符串严格的上升序列,则S‘<S,说明S'是S的真子集,所以可以从S'递推出S,无需再进行初始化。

记忆化搜索时,注意边界条件,每次都是在这里纠结,WA。

#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <string>#include <cmath>#include <algorithm>using namespace std;int d[30][30][600];bool vis[30][30][600];int L, S;int dp(int i, int j, int s){int &ans = d[i][j][s];if(j == 0) return (s == 0)? 1:0;if(s < 0 || i > 26 || j > 26 || s > 360) return 0;if(vis[i][j][s]) return ans;vis[i][j][s] = 1;ans = 0;for(int t = i; t <= 26; t++) ans += dp(t+1, j-1, s-t);return ans;}void solve(){int ans = dp(1, L, S);printf("%d\n", ans);}int main(){int times = 0;memset(vis, 0, sizeof(vis));while(scanf("%d%d", &L, &S) && (L || S)){printf("Case %d: ", ++times);solve();}return 0;}