UVALive 4236 Text Messaging Improvement?

http://livearchive.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2237


dp[i as i-th frequency(or letter)][j as we had used j key][k as the k-th position in j-th key]

so

dp[i][j][k] is formed by two parts: i-th letter can use a new key((j + 1)-th) or be a part of the j-th key in position k-th

as to show the arrangement of the letters, i define a structure to record the precursor

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <cctype>
#include <queue>
#include <stack>
using namespace std;
#define Rep(c, a, b) for (int c = (a); c < (b); c++)
#define Nre(c, a, b) for (int c = (a); c > (b); c--)
#define MAXN (52)
#define INFI (0x7fffffff)

struct Pre
{
	int i, j, k;
	Pre(int _i = 0, int _j = 0, int _k = 0)
		: i(_i), j(_j), k(_k)
	{}
} ps[MAXN][MAXN][MAXN];

int K;
double f[MAXN], dp[MAXN][MAXN][MAXN];

int main()
{
	int T;
	scanf("%d", &T);
	Rep(Cas, 1, T + 1)
	{
		scanf("%d", &K);
		double sf = 0;
		Rep(i, 1, 27)
		{
			Rep(j, 0, MAXN) Rep(k, 0, MAXN) dp[i][j][k] = INFI;
			Rep(j, 0, MAXN) Rep(k, 0, MAXN) ps[i][j][k] = Pre(0, 0, 0);
			scanf("%lf", f + i);
			sf += f[i];
		}
		dp[1][1][1] = f[1];
		Rep(i, 2, 27) Rep(j, 1, K + 1) Rep(k, 1, 9) 
		{
			if (j < K && dp[i - 1][j][k] < dp[i][j + 1][1] - f[i]) //use a new key
			{
				dp[i][j + 1][1] = dp[i - 1][j][k] + f[i];
				ps[i][j + 1][1] = Pre(i - 1, j, k);
			}
			if (k < 8 && dp[i - 1][j][k] < dp[i][j][k + 1] - (k + 1) * f[i]) // be a part of j-th key
			{
				dp[i][j][k + 1] = dp[i - 1][j][k] + (k + 1) * f[i];
				ps[i][j][k + 1] = Pre(i - 1, j, k);
			}
		}
		int mj = 1, mk = 1;
		Rep(j, 4, K + 1) Rep(k, 1, 9)//find the minimum keystrokes
			if (dp[26][j][k] < dp[26][mj][mk])
			{
				mj = j;
				mk = k;
			}
		int hash[MAXN]; //h[i] record the key where the i-th key in
		Pre nw(26, mj, mk);
		double ts = 0;
		while (nw.i && nw.j && nw.k)
		{
			hash[nw.i] = nw.j;
			ts += f[nw.i] * nw.k;
			nw = ps[nw.i][nw.j][nw.k];
		}
		printf("%d %.3lf ", Cas, ts / sf);
		for (int i = 1; i < 27;)
		{
			if (i > 1) putchar(' ');
			putchar('A' - 1 + i);
			for (i++; i < 27 && hash[i] == hash[i - 1]; i++) putchar('A' + i - 1);
		}
		puts("");
	}
	return 0;
}


in fact, dp[i][j] is enough XD
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值