hdu 1024和hdu 1244 两个最大和子序列 dp 优化
来源:互联网 发布:外贸通软件 编辑:程序博客网 时间:2024/05/22 06:17
hdu 1244
题目链接
思路:
dp[i][j] 表示前i个数(包括第i个数)取了j段的最大和,则转移方程为 dp[i][j]=max(dp[i-1][j],dp[i-b[j]][j-1]+s[i]-s[i-b[j]])
#include<bits/stdc++.h>#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while(a--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 100000007#define inf 0x3f3f3f3f#define exp 0.00000001#define pii pair<int, int>#define mp make_pair#define pb push_backusing namespace std;typedef long long ll;const int maxn=1e6+10;int gcd(int a,int b){return b==0?a:gcd(b,a%b);}int b[22],dp[1111][1111],n,m,s[1111];int main(){int w;while(~Ri(n)){if(n==0)break;Ri(m);s[0]=0;for(int i=1;i<=m;i++){Ri(b[i]);}for(int i=1;i<=n;i++){Ri(w);s[i]=s[i-1]+w;}CLR(dp,0);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=dp[i-1][j];if(i>=b[j])dp[i][j]=max(dp[i-1][j],dp[i-b[j]][j-1]+s[i]-s[i-b[j]]);}}Pi(dp[n][m]);}return 0;}
hdu 1024
题意:
最大和子序列的加强版,但是n 1e6 m 范围没给出
dp[i][j]表示前i个数取j组的最大值(包括第i个数)
转移方程: dp[i][j]=max(dp[i-1][j]+a[i],dp[k][j-1]+a[i]) j-1<=k<=i-1 (决策就是第i个数是独立成组还是和前一个数一起成组)
因为我们这里的n和m都很大,显然这样是会爆的.
那么我们就来想想优化,我们由转移方程观察可以得出dp[i][j]的值,只与dp[i-1][j]和 dp[*][j-1]有关,那么我们可以开两个一维数组一个维护 dp的值 一个维护 前j-1到i-1取j-1组的最大值; 前i个数分成j-1组的最大值我们在计算过程中可以得到...然后维护一下即可
#include<iostream>#include<string.h>#include<algorithm>#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while(a--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 100000007#define inf 0x3f3f3f3fusing namespace std;typedef long long ll;const int maxn=1e6+10;int dp[maxn],pre[maxn];int a[maxn];int m,n; void solve(){CLR(dp,0);CLR(pre,0);int ma;for(int i=1;i<=m;i++){ma=-inf;for(int j=i;j<=n;j++){dp[j]=max(dp[j-1]+a[j],pre[j-1]+a[j]);pre[j-1]=ma;ma=max(ma,dp[j]);}}Pi(ma);}int main(){while(~scanf("%d %d",&m,&n)){for(int i=1;i<=n;i++)Ri(a[i]);solve();}return 0; }
1 0
- hdu 1024和hdu 1244 两个最大和子序列 dp 优化
- HDU ACM 1024(最大子序列和)
- hdu 1231 最大连续子序列和( DP )
- HDU 1003 Max Sum(dp,最大连续子序列和)
- HDU 1003 Max Sum(dp,最大连续子序列和)
- HDU 1003--DP(最大子序列和)
- 【最大连续子序列和dp】hdu 1003 Max Sum
- HDU 2845 Beans(最大不连续子序列和 dp)
- HDU 1087 (DP---最大递增子序列和)
- 最大连续子序列和(经典DP) 之 hdu 1231 最大连续子序列
- HDU--1231 : 最大连续子序列 (DP求连续子序列最大和)
- HDU 1024 Max Sum Plus Plus(dp多段最大子序列和)*
- hdu 1231 最大连续子序列和
- HDU 1087 最大子序列和
- HDU 1003(最大子序列和)
- Max Sum hdu+最大子序列和
- hdu 1087 上升子序列最大和
- hdu 1003 求最大子序列和
- 加密与解密入门
- [深度学习论文笔记][CVPR 16]Deep Metric Learning via Lifted Structured Feature Embedding
- HDU
- 稀疏矩阵的压缩存储与转置与加法
- linux安装jupyter
- hdu 1024和hdu 1244 两个最大和子序列 dp 优化
- AC自动机(hdu2222)
- Prufer数列编码生成树
- linux vi模式下基本命令和快捷键
- vb.net 教程 5-8 Screen类
- 迷宫问题 POJ
- HTML+JS基础之a标签href与onclick事件的冲突处理
- 学习OpenCV2(四)——MeanShift之图形分割
- (C语言)高精度阶乘