码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 10581 - Partitioning for fun and profit(数论递推)

时间:2014-07-06 11:41:28      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   2014   

10581 - Partitioning for fun and profit

题目链接

题意:给定m, n,表示分配给n个格子,分配m个数字进去,每个格子最少1,并且序列要是递增的,问第k个字典序的序列是什么

思路:先利用dp打出表,dp[i][j][k]表示第i个数,尾巴为j,总和剩下k的情况,写一个记忆化求出,之后在这个数组基础上,从左往右枚举要放那个数字合适,合适的就放进去并且输出,注意最后一个数字要单独输出。

代码:

#include <cstdio>
#include <cstring>

typedef long long LL;
int t, M, n, vis[15][225][225];
LL k, dp[15][225][225];

LL DP(int now, int tail, int m) {
    LL &ans = dp[now][tail][m];
    if (vis[now][tail][m]) return ans;
    vis[now][tail][m] = 1;
    ans = 0;
    if (now == n) return ans = 1;
    if (now == n - 1) {
	if (m >= tail)
	    return ans = DP(now + 1, m, 0);
	return ans = 0;
    }
    for (int i = tail; i <= m - (n - now - 1); i++)
	ans += DP(now + 1, i, m - i);
    return ans;
}

void solve(LL k) {
    int v = 1;
    for (int i = 1; i < n; i++) {
	for (int j = v; j <= M - (n - i); j++) {
	    if (k > dp[i][j][M - j]) k -= dp[i][j][M - j];
	    else {
		M -= j;
		v = j;
		printf("%d\n", j);
		break;
	    }
	}
    }
    printf("%d\n", M);
}

int main() {
    scanf("%d", &t);
    while (t--) {
	memset(vis, 0, sizeof(vis));
	scanf("%d%d%lld", &M, &n, &k);
	DP(0, 1, M);
	solve(k);
    }
    return 0;
}


UVA 10581 - Partitioning for fun and profit(数论递推),布布扣,bubuko.com

UVA 10581 - Partitioning for fun and profit(数论递推)

标签:style   blog   http   color   os   2014   

原文地址:http://blog.csdn.net/accelerator_/article/details/37057765

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!