UVA 12105 - Bigger is Better(DP+高精度)

题目链接:12105 - Bigger is Better

题意:一些火柴,问你能组成整除m最大的数字是多少。

思路:dp[i][j]表示用i根火柴,组成%m余数为j的最大数字,末尾多一个数字k的状态就是dp[i + num[k]][(j * 10 + k) % m],由于最多可能50位数,所以要用高精度。

注意一个优化点,由于高精度的计算上只需要乘10+k,常规的高精度乘法复杂度还是有点高会超时,所以用数组去模拟,每次*10 + k的时候就往后多一位即可。

代码:

#include <stdio.h>
#include <string.h>

const int N = 105;
const int M = 3005;
const int num[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
int n, m;
char dp[N][M][55], ans[55], tmp[55];

void init() {
	scanf("%d", &m);
	memset(dp, 0, sizeof(dp));
	memset(ans, 0, sizeof(ans));
	dp[0][0][0] = ‘0‘;
}

int numcmp(char *a, char *b) {
	int lena = strlen(a);
	int lenb = strlen(b);
	if (lena < lenb) return -1;
	if (lena > lenb) return 1;
	return strcmp(a, b);
}

void DP(char *a, char *b, int k) {
	memset(tmp, 0, sizeof(tmp));
	strcpy(tmp, b);
	int len = strlen(b);
	if (tmp[0] == ‘0‘)
		tmp[0] = ‘0‘ + k;
	else
		tmp[len] = ‘0‘ + k;
	if (numcmp(a, tmp) < 0)
		strcpy(a, tmp);
}

int main() {
	int cas = 0;
	while (~scanf("%d", &n) && n) {
		init();
		for (int i = 0; i <= n; i++) {
			for (int j = 0; j < m; j++) {
				if (strlen(dp[i][j]) == 0) continue;
				for (int k = 0; k < 10; k++) {
					if (i + num[k] > n) continue;
					DP(dp[i + num[k]][(j * 10 + k) % m], dp[i][j], k);
				}
			}
			if (i != 0 && numcmp(ans, dp[i][0]) < 0)
				strcpy(ans, dp[i][0]);
		}
		printf("Case %d: ", ++cas);
		if (ans[0] == 0) printf("-1\n");
		else printf("%s\n", ans);
	}
	return 0;
}

UVA 12105 - Bigger is Better(DP+高精度),码迷,mamicode.com

时间: 2024-12-08 19:37:21

UVA 12105 - Bigger is Better(DP+高精度)的相关文章

UVa 12105 Bigger is Better (DP)

题意:用不超过 n 根火柴,组成一个尽可能大的数. 析:很明显的一个DP题,首先不难想到这个dp[i][j] 表示前 i 根火柴,所能拼出的取模 m 为 j 的数,状态转移方程也很好写, dp[i][j] ==> dp[i+c[k]][(j*10+k)%m] 其中 k 为在后面添加的数,c 数组是用的火柴数,这个方程没问题,就是效率有点低, 因为有一个高精度问题,可以用Java来实现,也能够AC的. 第二种方法就是换一个表示方法,不过确实不太容易想到.dp[i][j] 表示用最多 i 根火柴,取

Uva 10131-Is Bigger Smarter?(DP)

题目链接:点击打开链接 DAG(有向无环图)上的最长路+打印路径 建图很简单,对于两点 a b, 能够由a到b的条件是w[a]<w[b]&&s[a]>s[b] 注意是有向图. 设dp[i] 为以i为起点的最长路的长度,dp[i]= max(dp[i],dp[j]+1)  枚举j (j是和i相连的点) #include <algorithm> #include <iostream> #include <cstring> #include <

UVA - 10131Is Bigger Smarter?(DAG上的DP)

题目:UVA - 10131Is Bigger Smarter? (DAG) 题目大意:给出一群大象的体重和IQ.要求挑选最多的大象,组成一个序列.严格的体重递增,IQ递减的序列.输出最多的大象数目和这些大象的序列(当中一种就能够). 解题思路:DAG上的DP.和之前的一篇相似.uva437 - The Tower of Babylon(DAG上的DP).就是将每两仅仅大象满足上面的序列要求的形成一条有向边. 之后就是DAG上的DP.然后再路径输出. 代码: #include <cstdio>

UVA 10497 - Sweet Child Makes Trouble(DP+高精度)

题目链接:10497 - Sweet Child Makes Trouble 题意:n个物品,原来物品属于一个地方,现在要把物品重新放回去,问能放几种使得每个物品都与原来位置不同 思路:递推,一开始随便搞了个二维状态,dp[i][j]表示i个物品,有j个位置不同,那么dp[n][n]就是答案,递推式为: dp[i][j] = 1 (j == 0) dp[i][j] = (j - 1) * dp[i - 1][j - 1] + dp[i - 1][j] + (i - j + 1) * dp[i -

UVA 10131 Is Bigger Smarter?(DP最长上升子序列)

Description Question 1: Is Bigger Smarter? The Problem Some people think that the bigger an elephant is, the smarter it is. To disprove this, you want to take the data on a collection of elephants and put as large a subset of this data as possible in

uva 10497 - Sweet Child Makes Trouble(dp+高精度)

题目链接:uva 10497 - Sweet Child Makes Trouble 题目大意:有个小屁孩很淘气,总是趁父母不在家的时候去拿家具玩,每次拿n个家具玩,但是放回去的时候一定不会将某个物品放回原处,一定要打乱.问说有多少放的方式满足. 解题思路:dp[i]表示说i个数打乱的情况,dp[i]=(dp[i?1]+dp[i?2])?(i?1)每次新增一个数,放在序列的最后一个位置,它的位置一定是正确的,所以一定要和前面i?1个的其中一个交换位置才可以,那么如果选中位置上的物品为错误归放的,

poj 1625 Censored!(AC自动机+DP+高精度)

题目链接:poj 1625 Censored! 题目大意:给定N,M,K,然后给定一个N字符的字符集和,现在要用这些字符组成一个长度为M的字符串,要求不包 括K个子字符串. 解题思路:AC自动机+DP+高精度.这题恶心的要死,给定的不能匹配字符串里面有负数的字符情况,也算是涨姿势 了,对应每个字符固定偏移128单位. #include <cstdio> #include <cstring> #include <queue> #include <vector>

【bzoj2764】[JLOI2011]基因补全 dp+高精度

题目描述 在生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对,C总与G配对.两个碱基序列能相互匹配,当且仅当它们等长,并且任意相同位置的碱基都是能相互配对的.例如ACGTC能且仅能与TGCAG配对.一个相对短的碱基序列能通过往该序列中任意位置补足碱基来与一个相对长的碱基序列配对.补全碱基的位置.数量不同,都将视为不同的补全方案.现在有两串碱基序列S和T,分别有n和m个碱基(n>=m),问一共有多少种补全方案. 输入 数据包括三行. 第

bzoj 1089 [SCOI2003]严格n元树(DP+高精度)

1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1250  Solved: 621[Submit][Status][Discuss] Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严格2元树有三个,如下图: 给出n, d,编程数出深度为d的n元树数目. Inp