b 诗人小g.doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
b 诗人小g

窗体顶端 窗体底端 您查询的关键词是:诗人小g?报告? 。如果打开速度慢,可以尝试快速版;如果想保存快照,可以添加到搜藏。 (百度和网页/blog/noi-2009-poet/的作者无关,不对其内容负责。百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面。) ? Beyond the Void ? NOI 2009 变换序列 NOI 2009 二叉查找树 ? 一 12 NOI 2009 诗人小G NOI Add comments1,500 views 问题简述 有N个诗句需要被排版为若干行,顺序不能改变。一行内可以有若干个诗句,相邻诗句之间有一个空格。定义行标准长度L,每行的不协调度为|实际长度-L|P,整首诗的不协调度就是每行不协调度之和。任务是安排一种排版方案,使得整首诗的不协调度最小。 问题建模 这是一个最优化问题,抽象成动态规划模型。设第i个诗句的长度为Len[i],前i个诗句的总长度为SumL[i],。F[i]为对前i个诗句排版的最小不协调度。 解法1 朴素的动态规划 算法描述 显然每个F[i]可以被分解为F[j]和第j+1…i个句子组成一行的状态,所以状态转移方程为 简化后,可以书写成 在具体实现时,应记录每个状态的决策,以便于输出合法方案。考虑到“最小的不协调度超过1018输出”Too hard to arrange””,为防止64位整型运算溢出,可以先用浮点数类型计算,然后再用整型算出具体值。 复杂度分析 状态数为O(N),每次转移需要以O(N)的时间枚举j,所以时间复杂度为O(N2)。在实际测试中通过了测试点1,2,3,得到30分。 参考程序 ?View Code CPP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 /* * Problem: NOI2009 poet * Author: Guo Jiabao * Time: 2009.9.22 13:30 * State: Solved * Memo: 朴素动态规划 */ #include iostream #include cstdio #include cstdlib #include cmath #include cstring using namespace std; ? typedef long long big; ? const int MAXN=100001,SMAXL=32; const big INF=~0ULL1,LIMIT=1000000000000000000LL; ? big F[MAXN],sumL[MAXN]; int N,L,P; int Len[MAXN],deci[MAXN],sel[MAXN]; char sent[MAXN][SMAXL]; ? void init() { scanf(%d%d%d\n,N,L,P); for (int i=1;i=N;++i) { gets(sent[i]); Len[i] = strlen(sent[i]); sumL[i] = sumL[i-1] + Len[i]; } } ? big power(big a) { big t=1; double dt=1; if (a 0) a = -a; for (int i=1;i=P;i++) { dt *= a; if (dt LIMIT) return INF; t *= a; } return t; } ? void solve() { int i,j,k; big minv,t; for (i=1;i=N;++i) { minv = INF; for (j=0;j=i-1;++j) { t = power(sumL[i] - sumL[j] + i-j-1 - L); if ( double(t) + double(F[j]) = LIMIT t + F[j] minv) { minv = t + F[j];

文档评论(0)

zhengyl + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档