抄书uva714
来源:互联网 发布:互联网金融数据平台 编辑:程序博客网 时间:2024/04/29 18:46
题意:按顺序给你N个数,将这N个数分成连续的M段,使得这M段每段的和中的最大值最小,输出最小值(1<=N<=100000,1<=M<=N,每个数在1到10000之间),如果有多种可能的话,尽量在前面进行划分。
示例:
1 2 3 2 5 4
结果:
1 2 3 | 2 5 | 4
7
想法:我对这个题的理解就是暴力,是数组分割的一个变种,先对这n个数进行m段分割,然后分别记录下一组里的和,然后max更新最大值,最后再sort排一下序,得到最小的最大值。ps:我的方法只测试了几组数据而且代码不规范错漏肯定是有的。
代码:
#include<iostream>#include<algorithm>#include<string>using namespace std;struct node { string str; int a; int ms[1024];}sh[1024];int n, arr[1024], p[1024], k, m = 0;void dfs(int cur) { if (cur == n) { int sum = 0; for (int i = 0; i < n; i++) { sum += p[i];//获取标记的和,作用是固定分组数 } int su = 0, ans = 0; if (sum == k && !p[n - 1]) { for (int i = 0; i < n; i++) { ans += arr[i];//获取每一组的数值便于计算和 if (p[i] && i != n - 1) { sh[m].str.append(to_string(arr[i]));//获取每一组值便于后期输出 sh[m].str.append(" ");//分隔号 sh[m].ms[i] = ans;//获取每一组的和 su = max(su, ans);//求一串数中的最大和 // cout << arr[i] << ","; ans = 0;//分割号后从新计量下一个小分组的和 } else { sh[m].str.append(to_string(arr[i])); // cout << arr[i] << " "; } if (i == n - 1) { sh[m].ms[i] = ans;//将最后一个数放入结构体里 su = max(su, ans); } } sh[m++].a = su; //cout << endl; } return; } else { p[cur] = 1; dfs(cur + 1); p[cur] = 0; dfs(cur + 1); }}bool cmp(node a, node b) {//先让和从小到大排列,相同和的按照每一组的和从小到大排序 if (a.a > b.a)return 0; else if (a.a == b.a) { int x = 0; while (a.ms[x] == b.ms[x++]); if (a.ms[x] < b.ms[x])return 1; else return 0; } else return 1;}int main(void) { cin >> n >> k; memset(p, 0, sizeof(p)); for (int i = 0; i < n; i++) cin >> arr[i]; dfs(0); //cout << endl; sort(sh, sh + m, cmp); cout << sh[0].a << " " << sh[0].str << endl;; system("pause"); return 0;}
在此我再贴上一份别人的代码:
原文地址:https://www.cnblogs.com/g0feng/archive/2012/10/16/2726726.html
思路:
1、由于函数具有单调性的特征,因此可以用二分枚举的办法去实现它,这与POJ3258有非常相似的地方,但这里不需要排序。
2、输出的时候需要用到贪心的思想,既尽量往前划分。
3、大概的思路就是二分枚举求得满足题意的最大值之后,然后以这个最大值通过从后往前的方式划分成段,如果剩余可划分段与i+1的值相等(尽量靠前),则将剩余的段往前划分,具体实现可以用一个标记数组use表示是否划分。
5、注意high_bound可能超int,所以需要long long 来存。
#include <cstdio>#include <cstdlib>#include <iostream>#include <cstring>using namespace std;const int MAXN = 510;int a[MAXN], use[MAXN];long long low_bound, high_bound;int n, m;void init(){ low_bound = -1; high_bound = 0; memset(use, 0, sizeof(use));}int solve(int mid){ int sum = 0, group = 1; for(int i = n-1; i >= 0; i--) { if(sum + a[i] > mid) { sum = a[i]; group++; if(group > m) return 0; } else sum += a[i]; } return 1;}void print(int high_bound){ int group = 1, sum = 0; for(int i = n-1; i >= 0; i--) { if(sum + a[i] > high_bound) { use[i] = 1; sum = a[i]; group++; } else sum += a[i]; if(m-group == i+1) { for(int j = 0; j <= i; j++) use[j] = 1; break; } } for(int i = 0; i < n-1; i++) { printf("%d ", a[i]); if(use[i]) printf("/ "); } printf("%d\n", a[n-1]);}int main(){ int T; scanf("%d%*c", &T); while(T--) { init(); scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); if(low_bound < a[i]) low_bound = a[i]; high_bound += a[i]; } long long x = low_bound, y = high_bound; while(x <= y) { long long mid = x+(y-x)/2; if(solve(mid)) y = mid-1; else x = mid+1; } print(x); } return 0;}
阅读全文
0 0
- 抄书uva714
- UVA714 Copying Books (抄书)
- 例题8-10 抄书 UVa714
- UVA714:Copying Books(抄书)
- UVa714 例题8-10 抄书
- uva714
- uva714
- uva714
- uva714
- Uva714
- 抄书笔记
- 抄书问题
- 抄书问题
- 抄书问题
- unp抄书
- uva714 - Copying Books
- 最大值最小化--uva714
- uva714 - Copying Books
- Matlab中使用LIBSVM
- HDU 5914
- Windows10配置TensorFlow-GPU及Keras教程
- Android基础知识——Android SDK Manager详解
- ubuntu16.04下安装CUDA cuDNN及tensorflow-gpu版本及caffe-gpu过程
- 抄书uva714
- C++下使用libcurl实现微信公众号推送消息到粉丝账号
- 计算机八大核心期刊
- Spring面向切面编程三
- 中文教学视频 | 如何提升 Android Studio 在低配置机器上的运行速度
- 初装linux的一些配置
- java字符解码与编码
- 数组最长连续递增(+1)子序列
- hduoj 2009