【题解】T6775 拆数乘积
来源:互联网 发布:arpu值算法 编辑:程序博客网 时间:2024/06/06 15:34
原题链接
算法分析
要想 AC 此题,就先要用简单的数论和贪心找到最优解的组成方法。
以 2004 为例,由于把 2004 拆分成若干个互不相等的自然数的和的分法只有有限种,因而一定存在一种分法,使得这些自然数的乘积最大。
若 1 作因数,则显然乘积不会最大。把 2004 拆分成若干个互不相等的自然数的和,因数个数越多,乘积越大。为了使因数个数尽可能得多,我们把 2004 分成 2+3…+n 直到和大于等于 2004 。
若和比 2004 大 1,则因数个数至少减少 1 个,为了使乘积最大,应去掉最小的 2,并将最后一个数(最大)加上 1 。
若和比 2004 大 k(k ≠ 1),则去掉等于k的那个数,便可使乘积最大。
例如 15,s = 2+3+4+5+6,刚好大于 15,s - 15 = 5,所以把 5 去掉。
又例如 13,s = 2+3+4+5,刚好大于 13,s - 13 = 1,所以去掉 2,并把 5 加 1 ,即 3 4 6 。
示例代码
#include <iostream>using namespace std;int n , sum , ans[10001] , c = 1;//ans数组用来存拆分出来的数int main(){ ios::sync_with_stdio(0); cin >> n; if ( n <= 4 )//特判,如果n小于等于4,自己本身就是最优解 { cout << n; return 0; } for ( int i = 2 ; i <= n ; i++ )//2到n循环 {if ( n >= i ){ n -= i;//每拆分出1个数,n就减去这个数 ans[c++] = i;//把i存下来 } else break;//不能再拆分就终止循环 } for ( int i = c - 1 ; i >= 1 ; i-- )//逆序倒推 if ( n > 0 ) ans[i]++ , n--;//多的数分担给其他数 if ( n > 0 ) ans[c-1]++;//如果还多,就分给最后一个数 for ( int i = 1 ; i < c ; i++ ) cout << ans[i] << " ";//输出每一个拆分出来的数 return 0;}
- 【题解】T6775 拆数乘积
- 乘积最大【题解】
- 【题解】T6079 乘积大小
- 两数乘积运算
- 乘积是平方数
- 两个数的乘积
- 两个数的乘积
- 数的乘积 双dp
- 两数乘积的位数
- 求一个数的连乘积
- 将一个数分解为素数乘积
- 计算两数的乘积,求最大值
- 用函数重载输出两数乘积
- n数乘积第m小
- 基类 派生类 算一个数乘积
- MSTC "数独" 题解
- 数石子题解
- [统计数对] 题解
- DEVOPS
- 怎样解决warning LNK4099: 未找到 PDB“vc100.pdb” 造成的链接 时间过长
- 网站防止XSS攻击
- hdu2586 lca+rmq
- MySql用户权限控制 【转】
- 【题解】T6775 拆数乘积
- windows MAC linux XMODEM YMODEM使用方法
- 中间镂空效果:A 视图上叠加 B视图,只显示B视图中间部分,达到好像中间镂空的效果
- 2-用Python搭建一个SSH僵尸网络
- 【excel 函数】常用的Excel函数
- Java数组
- HDU 4109 Instrction Arrangement (拓扑or差分约束求关键路径)
- cenos7安装svn
- Python:练习题(列表推导式、词频统计、异常处理、正则表达式等)