uvalive-6190(二分+dp验证)

Beautiful Spacing

链接

题意:

  文本每行有w列,有n个单词。排列规则如下:

  1、每两个单词之间必须有空格

  2、除了最后一行,每行第一个单词第一个字母必须顶格,最后一个单词最后一个字母必须在最后一格。

  3、同一个单词不能换行

  要使得最大间隔最小

解决:

  使最大值最小的问题,显然二分。

  验证的时候不能像一般题目贪心验证。

  dp[i]为第i个单词做开头的时候,对于待验证值x,枚举可行结尾j,则每个可行结尾j对应了下一个可行开头 j + 1,这样一来状态转移就出来了,朴素的dp中n^2的复杂度被减枝很多。再者,如果 [i, j]这一段中,每两个的单词之间空位都是x,且仍不能填满一行,则[i+1, j]一定也不能达到填满一行的要求。所以这个时候,对于每个可行开头i, 枚举可行结尾的时候,不用再从i+1开始。

 

 1 #include <bits/stdc++.h>
 2 
 3 const int MAXN = 50000+10;
 4 
 5 int w, n;
 6 int a[MAXN];
 7 int s[MAXN];
 8 bool dp[MAXN];
 9 
10 bool check(int x)
11 {
12 //    printf("check(%d)\n", x);
13     memset(dp, false, sizeof(dp));
14     dp[1] = true;
15     if (s[n] + n - 1 <= w)
16         return true;
17     for (int l = 1, t = 2; l <= n; ++l) {
18         if (dp[l] == true) {
19             for (int r = std::max(l+1, t); r <= n; ++r) {
20                 int cnt = r - l + 1;
21                 int len = s[r] - s[l-1];
22                 int max_len = (cnt-1)*x + len;
23                 int min_len = cnt - 1 + len;
24 //                printf("l = %d, r = %d, min_len = %d, max_len = %d\n", l, r, min_len, max_len);
25                 if (min_len > w)
26                     break;
27                 if (max_len < w)
28                     continue;
29                 dp[r + 1] = true;
30 //                printf("r = %d\n", r);
31                 t = r+1;
32                 if (s[n] - s[r] + n - r <= w) {
33                     return true;
34                 }
35             }
36         }
37     }
38 //    printf("false!!\n");
39     return false;
40 
41 }
42 
43 int main()
44 {
45 
46     while (~scanf("%d%d", &w, &n)) {
47         if (w == 0 && n == 0)
48             break;
49         s[0] = 0;
50         for (int i= 1; i <= n; ++i)
51             scanf("%d", a+i), s[i] = s[i-1] + a[i];
52         if (s[n] + n-1 <= w) {
53             printf("%d\n", 1);
54             continue;
55         }
56         int l = 1, r = w;
57         while (l <= r) {
58             int mid = l + r >> 1;
59             if (check(mid)) {
60                 r = mid - 1;
61             }
62             else
63                 l = mid + 1;
64         }
65         printf("%d\n", l);
66     }
67     return 0;
68 }

 

posted on 2015-11-08 13:00  TakeoffYoung 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/takeoffyoung/p/4947175.html

基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值