UESTC 1214 divide && PKU 3390 Print Words in Lines [DP]
2010-05-19 22:43
435 查看
UESTC 1214 divide && PKU 3390 Print Words in Lines [DP]
两个题有些类似,都是在限定一段连续的区间内元素之和不大于给的M,都是DP解决;
UESTC的1214元素存在负数,因此贪心是不对的;
UESTC1214 二分+dp
题意:给定一个N个元素的序列,不能改变顺序,将N个元素分为M(M<=N)堆,最小化 最大的每堆的和,求之;
很容易想到对答案ans二分,因为ans满足单调性(如果ans可以的话,大于ans的值都可以满足);
然后就是判定在该ans下能否分为不大于M堆得到的“最大的每堆的和”小于等于ans;
判定部分要用dp解决,注意一个最优子结构;
令dp[i]表示前i个数分成的每堆都小于等于ans的最小堆数;
则dp[i]=min(dp[i],dp[j]+1) 其中j<i&&sum[i到j]<=ans;
复杂度为O(N^2*logN)
PKU 3390
题意:对单词进行分行,每行包括空格的字符数最多有M个;另实际该行数为s,每行权值A=(M-s)*(M-s);
目标是令权值之和最小,输出值;
此题是刚那个题的简单版本。做法类似,没有二分的部分;
另dp[i]为前i个单词分割成行后的最小值。
令s=j+1到i字符数之和,显然s<=M;
则dp[i]=min(dp[i],dp[j]+(M-s)*(M-s)); j<i;
复杂度为O(N*M);
两个题有些类似,都是在限定一段连续的区间内元素之和不大于给的M,都是DP解决;
UESTC的1214元素存在负数,因此贪心是不对的;
UESTC1214 二分+dp
题意:给定一个N个元素的序列,不能改变顺序,将N个元素分为M(M<=N)堆,最小化 最大的每堆的和,求之;
很容易想到对答案ans二分,因为ans满足单调性(如果ans可以的话,大于ans的值都可以满足);
然后就是判定在该ans下能否分为不大于M堆得到的“最大的每堆的和”小于等于ans;
判定部分要用dp解决,注意一个最优子结构;
令dp[i]表示前i个数分成的每堆都小于等于ans的最小堆数;
则dp[i]=min(dp[i],dp[j]+1) 其中j<i&&sum[i到j]<=ans;
复杂度为O(N^2*logN)
]#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int MAX=1500; const int INF=0x1fffffff; int dp[MAX],N,a[MAX],M,sum[MAX]; bool ok(int Line) { int i,j,k; for(i=1;i<=N;i++) dp[i]=INF; for(i=1;i<=N;i++) { if(sum[i]<=Line) {dp[i]=1;continue;} for(j=i-1;j>=0;j--) { //if(sum[i]-sum[j]>Line) break; if(dp[j]!=INF&&sum[i]-sum[j]<=Line) { dp[i]=min(dp[j]+1,dp[i]); } } } return dp <=M; } int main() { int i,j,T;scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); sum[0]=0; for(i=1;i<=N;i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } dp[0]=0; int l=-100000,r=100000,mid=0; while(l<r) { if(ok(mid)) r=mid; else l=mid+1; mid=(l+r)/2; } printf("%d/n",mid); } system("pause"); return 0; }
PKU 3390
题意:对单词进行分行,每行包括空格的字符数最多有M个;另实际该行数为s,每行权值A=(M-s)*(M-s);
目标是令权值之和最小,输出值;
此题是刚那个题的简单版本。做法类似,没有二分的部分;
另dp[i]为前i个单词分割成行后的最小值。
令s=j+1到i字符数之和,显然s<=M;
则dp[i]=min(dp[i],dp[j]+(M-s)*(M-s)); j<i;
复杂度为O(N*M);
]// poj 3390 print words in line #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int MAX=10100; const int INF=0x1fffffff; int N,M,a[MAX],sum[MAX]; int dp[MAX]; void gs() { int i,j; for(i=1;i<=N;i++) { int tt=sum[i]+i-1; if(tt<=M) {dp[i]=(M-tt)*(M-tt);continue;} tt=a[i]; dp[i]=dp[i-1]+(M-tt)*(M-tt); for(j=i-1;j>=1;j--) { if(tt+a[j]+1>M) break; int yy=tt+a[j]+1; dp[i]=min(dp[i],dp[j-1]+(M-yy)*(M-yy)); tt=yy; } } } int main() { int i,j,T;scanf("%d",&T); while(T--) { scanf("%d%d",&M,&N); sum[0]=0; for(i=1;i<=N;i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } gs(); //for(i=1;i<=N;i++) cout<<dp[i]<<" ";cout<<endl; printf("%d/n",dp ); } system("pause"); return 0; }
相关文章推荐
- POJ 3390 Print Words in Lines(DP)
- POJ 3390 Print Words in Lines(DP)
- POJ 3390 Print Words in Lines(DP)
- poj 3390 Print Words in Lines——简单DP
- poj 3390 Print Words in Lines
- poj 3390 Print Words in Lines 动态规划
- poj 3390 Print Words in Lines 动态规划
- [POJ3390 Print Words in Lines]
- [dp]POJ2559 && HDOJ1506 Largest Rectangle in a Histogram
- UESTC 1131 男神的礼物 dp:最优矩阵链乘&&triangulation&&双dp
- hdu 4791 Alice's Print Service (DP+离线处理)
- !HDU 1025 Constructing Roads In JGShining's Kingdom--DP--(LIS算法)
- Keyboard Row && Reverse Words in a String III
- Pku acm 2075 Tangled in Cables数据结构题目解题报告(十一)最小生成树:prim算法&amp;amp;二叉查找树
- HDU 1506 Largest Rectangle in a Histogram(DP·单调栈)
- leetcode day1 -- Reverse Words in a String && Evaluate Reverse Polish Notation && Max Points on a Li
- 329. Longest Increasing Path in a Matrix(DFS & DP)
- LeetCode: Reverse Words in a String && Rotate Array
- printscreen&nbsp;in&nbsp;Windows/CE/Mobile
- PKU_ACM_2388_Who's in the Middle