https://scut.online/p/299
\(dp[i][k]\) 为前 \(i\) 个数分 \(k\) 组的最大值,那么 $dp[i][k]=max_{p=1}^{i-1}{dp[p][k-1]*sum(p+1,i)} $

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;struct BigInt {const static int mod = 10000;const static int DLEN = 4;vector<int> a;int len;BigInt() {a.resize(1);len = 1;}BigInt(int v) {a.resize(2);len = 0;do {a[len++] = v%mod;v /= mod;} while(v);}BigInt operator +(const BigInt &b)const {BigInt res;res.len = max(len,b.len);res.a.resize(res.len+1);for(int i = 0; i <= res.len; i++)res.a[i] = 0;for(int i = 0; i < res.len; i++) {res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);res.a[i+1] += res.a[i]/mod;res.a[i] %= mod;}if(res.a[res.len] > 0)res.len++;return res;}BigInt operator *(const BigInt &b)const {BigInt res;res.a.resize(len + b.len);for(int i = 0; i < len; i++) {int up = 0;for(int j = 0; j < b.len; j++) {int temp = a[i]*b.a[j] + res.a[i+j] + up;res.a[i+j] = temp%mod;up = temp/mod;}if(up != 0)res.a[i + b.len] = up;}res.len = len + b.len;while(res.a[res.len - 1] == 0 &&res.len > 1)res.len--;res.a.resize(res.len);return res;}bool operator >(const BigInt &b)const {if(len>b.len)return true;else if(len==b.len) {int ln=len-1;while(a[ln]==b.a[ln]&&ln>=0)ln--;if(ln>=0&&a[ln]>b.a[ln])return true;elsereturn false;} elsereturn false;}void output() {printf("%d",a[len-1]);for(int i = len-2; i >=0 ; i--)printf("%04d",a[i]);printf("\n");}
};int a[205];
BigInt dp[205][205];
//区间[i,j]分为k段取得的最大值inline int suma(int i,int j) {return a[j]-a[i-1];
}int main() {
#ifdef Yinkufreopen("Yinku.in","r",stdin);
#endif // Yinkuint n,k;scanf("%d%d",&n,&k);for(int i=1; i<=n; i++) {scanf("%d",&a[i]);}for(int i=1; i<=n; i++) {a[i]+=a[i-1];}for(int i=1; i<=n; i++)dp[i][1]=BigInt(suma(1,i));for(int i=2; i<=n; i++) {int c=min(i,k);for(int ki=2; ki<=c; ki++) {for(int p=1; p<=i-1; p++) {BigInt t=dp[p][ki-1]*BigInt(suma(p+1,i));if(t>dp[i][ki])dp[i][ki]=t;}}}dp[n][k].output();
}

带FFT优化,反而更慢。这个可以理解。本身乘法是\(O(nm)\),这里m小到不行。你还搞个\(O(nlogn)\)?

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;const int MAXN=1e6+10;
inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;
}const double Pi=acos(-1.0);
struct Complex {double x,y;Complex(double xx=0,double yy=0) {x=xx,y=yy;}Complex operator+(const Complex& b)const {return Complex(x+b.x,y+b.y);}Complex operator-(const Complex& b)const {return Complex(x-b.x,y-b.y);}Complex operator*(const Complex& b)const {return Complex(x*b.x-y*b.y,x*b.y+y*b.x);}
} a[MAXN],b[MAXN];int l,r[MAXN];
int limit;void FFT(Complex *A,int type) {for(int i=0; i<limit; i++)if(i<r[i])swap(A[i],A[r[i]]);for(int mid=1; mid<limit; mid<<=1) {Complex Wn(cos(Pi/mid), type*sin(Pi/mid));for(int R=mid<<1,j=0; j<limit; j+=R) {Complex w(1,0);for(int k=0; k<mid; k++,w=w*Wn) {Complex x=A[j+k],y=w*A[j+mid+k];A[j+k]=x+y;A[j+mid+k]=x-y;}}}
}void Mult(const int &n,const int &m,const vector<int> &A,const vector<int> &B) {for(limit=1,l=0; limit<=n+m;limit<<=1)l++;memset(a,0,sizeof(a[0])*limit);memset(b,0,sizeof(b[0])*limit);for(int i=0; i<=n; i++)a[i].x=A[i];for(int i=0; i<=m; i++)b[i].x=B[i];for(int i=0; i<limit; i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));FFT(a,1);FFT(b,1);for(int i=0; i<=limit; i++)a[i]=a[i]*b[i];FFT(a,-1);for(int i=0; i<=n+m+2; i++) {a[i].x=(ll)(a[i].x/limit+0.5);}return;
}struct BigInt {const static int mod = 10000;const static int DLEN = 4;vector<int> a;int len;BigInt() {a.resize(4);len = 1;}BigInt(int v) {a.resize(4);len=0;do {a[len++]=v%mod;v/=mod;} while(v);}BigInt operator +(const BigInt &b)const {BigInt res;res.len=max(len,b.len);res.a.resize(res.len+4);for(int i=0; i<res.len; i++) {res.a[i]+=((i<len)?a[i]:0)+((i<b.len)?b.a[i]:0);res.a[i+1]+=res.a[i]/mod;res.a[i]%=mod;}if(res.a[res.len]>0)res.len++;return res;}BigInt operator *(const BigInt &b)const {BigInt res;res.a.resize(len+b.len+4);for(int i=0; i<len; i++) {int up=0;for(int j=0; j<b.len; j++) {int temp=a[i]*b.a[j]+res.a[i+j]+up;res.a[i+j]=temp%mod;up=temp/mod;}if(up != 0)res.a[i+b.len]=up;}res.len=len+b.len;while(res.len>1&&res.a[res.len-1]==0)res.len--;return res;}bool operator >(const BigInt &b)const {if(len>b.len)return true;else if(len==b.len) {int ln=len-1;while(a[ln]==b.a[ln]&&ln>=0)ln--;if(ln>=0&&a[ln]>b.a[ln])return true;elsereturn false;} elsereturn false;}void output() {printf("%d",a[len-1]);for(int i=len-2; i>=0; i--)printf("%04d",a[i]);printf("\n");}
};BigInt BigInt_Mult_FFT(const BigInt &A,const BigInt &B) {Mult(A.len-1,B.len-1,A.a,B.a);BigInt res;res.len=A.len+B.len-1;res.a.resize(res.len+4);for(int i=0; i<res.len; i++)res.a[i]=a[i].x;while(res.len>1&&res.a[res.len-1]==0)res.len--;for(int i=0; i<res.len; i++) {res.a[i+1]+=res.a[i]/BigInt::mod;res.a[i]%=BigInt::mod;}if(res.a[res.len]>0)res.len++;return res;
}int arr[205];
BigInt dp[205][205];
//区间[i,j]分为k段取得的最大值inline int sumarr(int i,int j) {return arr[j]-arr[i-1];
}int main() {
#ifdef Yinkufreopen("Yinku.in","r",stdin);
#endif // Yinkuint n,k;scanf("%d%d",&n,&k);for(int i=1; i<=n; i++) {scanf("%d",&arr[i]);}for(int i=1; i<=n; i++) {arr[i]+=arr[i-1];}for(int i=1; i<=n; i++) {dp[i][1]=BigInt(sumarr(1,i));}for(int i=2; i<=n; i++) {int c=min(i,k);for(int ki=2; ki<=c; ki++) {for(int p=1; p<=i-1; p++) {//BigInt t=dp[p][ki-1]*BigInt(sumarr(p+1,i));BigInt t=BigInt_Mult_FFT(dp[p][ki-1],BigInt(sumarr(p+1,i)));if(t>dp[i][ki]) {dp[i][ki]=t;}}}}dp[n][k].output();
}

转载于:https://www.cnblogs.com/Yinku/p/11026073.html

SCUT - 299 - Kaildls的数组划分 - dp - 高精相关推荐

  1. 【区间DP+高精】codevs1166 矩阵取数游戏题解

    转自: [ametake版权所有]http://blog.csdn.net/ametake欢迎来看 http://blog.csdn.net/ametake/article/details/47664 ...

  2. 【日常学习】【区间DP+高精】codevs1166 矩阵取数游戏题解

    题目来自NOIP2007TG3 如果在考场上我现在已经歇菜了吧 今天一整天的时间全部投在这道题上,收获不小. 先上题目 题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏 ...

  3. P2159 [SHOI2009]舞会(DP高精)

    P2159 [SHOI2009]舞会(DP&高精) n=200n=200n=200,考虑n3n^3n3的dpdpdp,但是本题没有模数,所以要高精度,且高精常数巨大,所以考虑n2n^2n2 的 ...

  4. 【luogu1018】 乘积最大 [区间dp+高精][noip2000]

    P1018 乘积最大 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大. DP+高精 #include<bits/stdc++ ...

  5. 【每日DP】day 10、P1005 矩阵取数游戏【区间DP+高精(python)】难度⭐⭐⭐★

    P1005 矩阵取数游戏 输入 2 3 1 2 3 3 4 2 输出 82 说明/提示 NOIP 2007 提高第三题. 数据范围: 60%60\%60% 的数据满足:1≤n,m≤301\le n,m ...

  6. 【状压DP+高精】【cofun1370】走道铺砖问题

    [cofun1370]走道铺砖问题 Description 有一个专门为装修设计方案的设计师.在某一天,他接到了一个项目,为一栋正在修建的大楼设计走道的地板铺设方案.此项目的委托人事先便进行了说明:地 ...

  7. bzoj1089 [SCOI2003]严格n元树(dp+高精)

    1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 1899  Solved: 954 [Submit][Sta ...

  8. 高精四则运算及求模运算(五)

    高精四则运算及求模运算之高精度求模 题目描述 Tenshi非常幸运地被选为掌管智慧之匙的天使.在正式任职之前,她必须和其他新当选的天使一样要宣誓. 宣誓仪式是每位天使各自表述自己的使命,他们的发言稿放 ...

  9. 【DP】【高精】WZK打雪仗(jzoj 1997)

    WZK打雪仗 jzoj 1997 题目大意: 在一个环上有n*2个点,问有多少种连法可以用n条线连接成n对点 输入样例 5 输出样例 42 解释: 一种可行的方案如下: 数据范围 对于30%数据: n ...

最新文章

  1. 实验mongodb使用gridfs存放一个大文件
  2. 创新的前端 豆瓣书评 摘录
  3. 学习python需要什么基础-学习python需要什么基础吗?老男孩Python
  4. MySQL高级知识(十五)——主从复制
  5. SpringBoot连接Redis超简单
  6. windows脚本编制引擎_说说 Windows 脚本宿主运行的几种方式
  7. 终于!商汤科技开源DAVIS2017视频目标分割冠军代码
  8. Flutter OpenContainer 容器转换过渡 Material Design 设计风格的实践
  9. HttpHandler和ashx要实现IRequiresSessionState接口才能访问Session信息(转载)
  10. 大数据技术原理与应用(最后三天备考!!!)
  11. SpringBoot+Druid连接池
  12. java球的体积计算
  13. 激活Windows系统的方式
  14. 多多情报通:拼多多推广账户金额可以通用吗?里面钱可以提出来吗?
  15. logout 注销登录
  16. 风林评《如何写影评》|如何写影评
  17. springboot实战,实现发送邮件,gmail邮件,包括发送附件还有正文,以及注意覆盖问题
  18. github 修改密码密码_雇主要求提供GitHub密码。 如何处理呢?
  19. 云计算运维工程师前景怎么样?
  20. Geoserver+Geomesa+HBase时空大数据环境搭建

热门文章

  1. 进程间通信——Queue
  2. 深度学习之人脸检测实践-现有框架实现 opencv Face++
  3. 浏览器兼容之JavaScript篇——已在IE、FF、Chrome测试
  4. 用Proteus学习51单片机之I2C(IIC)总线
  5. 如何过滤某一频率的声音
  6. 解决JupyterLab中tqdm_notebook进度条不显示问题
  7. opencv+python视频实时质心显示
  8. Topic model相关文章总结
  9. 多元分类SVM(多类别SVM)程序使用说明
  10. opencv双目视觉标定、匹配和测量 (附代码)(转载)