接着上一篇文章。

上次一次写的有点长了,保存好半天不成功,这次短一点吧,5道题目。

题目链接地址:http://acm.hdu.edu.cn/problemclass.php?id=516

ProID 1081 To The Max

题目大意是,给一个二维数组,让你求一个和最大的子矩阵。

也算是一道比较简单的题目了,这个除了用暴力法外,比较经典的做法是DP,这个其实也是那个最大子序列和的一个变种。来看看为什么。

比如说求这个矩阵的最大子序列和:

0 -2 -7 0

9 2 -6 2

对于第一行来说,其实就是求一个连续子序列之和,对于两行来说,把他们加起来得到序列 9,0,-13,2,同样也是求最大子序列和。好了问题解决了。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;int data[101][101];
int sumdata[101];
int main()
{while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&data[i][j]);int maxNum=-100000;for(int i=1;i<=n;i++)//行递增{memset(sumdata,0,sizeof(sumdata));for(int j=i;j<=n;j++)//高度从i到n的矩阵{//当前行的所有列相加,然后求最长子序列和,记录最大值for(int k=1;k<=n;k++)sumdata[k]+=data[j][k];int maxTemp=-100000;int sum = 0;for(int k=1;k<=n;k++){sum += sumdata[k];maxTemp = max(sum,maxTemp);sum = sum>0?sum:0;}maxNum=max(maxNum,maxTemp);}}printf("%d\n",maxNum);}return 0;
}

ProID 1087 Super Jumping! Jumping! Jumping!

题目大意是求一个最长上升子序列,在上一篇文章中已经讲过类似的问题了,不过是用二分查找做的,因为这道题目是要求输出序列之和,就得老老实实用原方法了。

代码如下:

#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cctype>
using namespace std;int data[1001];
int dp[1001];
int tmp[1001];
int main()
{int n;while(scanf("%d",&n)!=EOF,n){memset(dp,0,sizeof(dp));memset(tmp,0,sizeof(tmp));for(int i=0;i<n;i++)scanf("%d",&data[i]);dp[0]=data[0];tmp[0]=0;int sum=0;for(int i=1;i<n;i++){dp[i]=data[i];for(int j=0;j<i;j++){if(data[i]>data[j] && dp[i]<dp[j]+data[i])dp[i]=dp[j]+data[i];sum=max(sum,dp[i]);}}printf("%d\n",sum);}return 0;
}

ProID 1114 Piggy-Bank

题目意思是给定一些硬币,有重量和价值,然后给一个一定重量的罐子,问在能否在装满罐子的条件下,猜到这个罐子的最小价值。这个是完全背包,在背包九讲中有详细的解释。也只是套个公式而已,需要注意初始化问题。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int t;
int dp[10005];
struct _data
{int a,b;
};
_data data[501];int main()
{while(scanf("%d",&t)!=EOF){int E,F,n;while(t--){scanf("%d %d",&E,&F);scanf("%d",&n);memset(dp,0,sizeof(dp));bool flag=false;for(int i=0;i<n;i++){scanf("%d %d",&data[i].a,&data[i].b);if(data[i].b<F-E)flag=1;}if(!flag)printf("This is impossible.\n");else{//初始化和01背包不一样for(int i=1;i<=F-E;i++)dp[i]=5000000;//完全背包问题dp[i][j]表示考虑前i个物品在重量为j的情况下得到的最小价值for(int i=0;i<n;i++){for(int j=data[i].b;j<=F-E;j++){dp[j]=min(dp[j],dp[j-data[i].b]+data[i].a);}}if(dp[F-E]!=5000000)printf("The minimum amount of money in the piggy-bank is %d.\n",dp[F-E]);elseprintf("This is impossible.\n");}}}return 0;
}

ProID 1121 Complete the Sequence

题目大意是,给顶你一个符合P(n)=P(n) = aD.n^D+aD-1.n^D-1+...+a1.n+a0 多项式的序列,然后让你续填m个序列,说白了就是找出一个序列的规律来,就是按规律填数。

咋一看之下好像无从下手,a(*)怎么找啊,n如何确定?其实吧多项式相减就可以看出规律来,因为这个多项式是比较简单的相邻数相减就可消去高次方,然后再减可以消去下一个高次方。例子如下:

对于序列  1,2,3,4,7来说,

0 1 2 4 7
1 1 2 3 --
2 1 1 -- --
3 0 -- -- --

表格中描述的是3次相减之后的情况,总是可以在最后一步(也就是第n-1次相减中变为一个数字)现在来计算序列之后的数字,从下往回推:

3 0 0 -- -- --
2 1 1 1 -- --
1 1 2 3 4 --
0 1 2 4 7 11

来看看表格中第3行第3列的2是如何推导出来的,记住了差值是连续的两项的差,所以2=第二行第二列+第三行第2列的值,所以最后的11=第3行第5列的4+第四行第5列的7。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>using namespace std;int n,m,t,s[105][105];
int main()
{while(scanf("%d",&t)!=EOF){while(t--){scanf("%d %d",&n,&m);for(int i=0;i<n;i++)scanf("%d",&s[0][i]);for(int i=1;i<n;i++)//计算n阶差值for(int j=0;i+j<n;j++)s[i][j]=s[i-1][j+1]-s[i-1][j];for(int i=1;i<=m;i++)s[n-1][i]=s[n-1][0];//还原过程for(int i=n-2;i>=0;i--)for(int j=0;j<m;j++)s[i][n-i+j]=s[i][n-i+j-1]+s[i+1][n-i+j-1];//输出m需要求的值for(int i=0;i<m-1;i++)printf("%d ",s[0][n+i]);printf("%d\n",s[0][n+m-1]);}}return 0;
}

ProID  1158 Employment Planning

题目大意是老板要雇一群人工作,雇人和解雇都要付工资,工作的时候要付薪水,而且不工作也要付(真好啊 )。问你帮忙计算出完成一项工作所需的最小花费。

这道题目很类似于前一篇文章中的星河战队问题,只不过这个比那道题目稍微简单一些,因为是线性的,不是树形的。

状态转移方程如下:

Dp[i][j]为前i个月的留j个人的最优解;  其中 Num[i]<=j<=Max{Num[i]};  Num 数组表示的是当前这个月所需的最少人数,当然如果所雇用的人数绝对不超过所有月份中所多的人数,否则白白养那么一群人,老板也太好了。
对于Num[i]<=k<=Max_n,    当k<j时, 招聘;当k>j时, 解雇  然后求出最小值。Dp[i][j]=min{Dp[i-1][k…Max_n]+(招聘,解雇,工资);

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;int dp[13][1005],num[13];int n;
int hire,fire,salary;
int main()
{while(scanf("%d",&n),n){int MaxNum=0;scanf("%d%d%d",&hire,&salary,&fire);//如果说其中某个月所需要的人最多,那么总的人数不会超过这个,否则就是这个老板太慈善了。for(int i=0;i<n;i++){scanf("%d",&num[i]);MaxNum=max(MaxNum,num[i]);}memset(dp,0,sizeof(dp));for(int i=num[0];i<=MaxNum;i++){dp[1][i]=i*(salary+hire); //hire 也要加上}for(int i=2;i<=n;i++){for(int j=num[i-1];j<=MaxNum;j++){int Min=0xffffff;for(int k=num[i-2];k<=MaxNum;k++)//上个月雇佣的人数{//当k<j时, 招聘, 当k>j时, 解雇,  然后求出最小值if(k>j)Min=min(Min,dp[i-1][k]+(k-j)*fire+j*salary);else Min=min(Min,dp[i-1][k]+(j-k)*hire+j*salary);}dp[i][j]=Min;}}int ans=0xffffff;for(int i=num[n-1];i<=MaxNum;i++) ans=min(ans,dp[n][i]);printf("%d\n",ans);}return 0;
}

杭电60道DP问题总结(二)相关推荐

  1. 杭电60道DP问题总结(一)

    杭电60道DP问题总结: DP是一个很有艺术的思想.看似简单的背后却隐藏着深刻的含义. 题目连接地址:http://acm.hdu.edu.cn/problemclass.php?id=516& ...

  2. 杭电60道DP问题总结(三)

    接着前两篇,还是5道一贴吧. 题目链接地址:http://acm.hdu.edu.cn/problemclass.php?id=516 ProID 1159  Common Subsequence 题 ...

  3. 杭电46道DP牛人总结

    原文地址:杭电46道DP牛人总结作者:飞泉鸣玉 杭电46道DP牛人总结 HDU 动态规划(46道题目)倾情奉献~ [只提供思路与状态转移方程] 收藏 Robberies http://acm.hdu. ...

  4. 杭电60题--part 1 HDU1003 Max Sum(DP 动态规划)

    最近想学DP,锻炼思维,记录一下自己踩到的坑,来写一波详细的结题报告,持续更新. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Problem ...

  5. 【ACM】杭电OJ 4548 美素数(二次打表)

    二次打表,第一次是标记哪些是素数,哪些不是. 第二次是前n个数中   "本身是素数  &&  各个位上的和是素数  " 的个数 TLE: #include < ...

  6. 杭电2151 Worm dp

    Worm Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  7. 杭电计算机组成实验2(二)超前进位加法器设计实验

    实验内容 掌握运用Verilog HDL进行数据流描述与建模的技巧和方法,掌握模块调用与实例引用的方法 掌握超前进位加法器的原理与设计方法 解决方法 分析4位的二进制全加器的输入输出,内部为超前进位逻 ...

  8. 20杭电计算机专业考研科目,20杭电计算机菜鸡跨考经验贴

    20杭电计算机菜鸡跨考经验贴 心路历程 初试 复试 第一次写帖子,记录一下这一年多的努力成功上岸杭电,同时也是延续一下传统,去年也是在csdn和王道论坛上看到学长学姐的各种经验帖,从中得到很多重要的信 ...

  9. 2022杭电多校(一)

    2022杭电多校(一) 文章目录 2022杭电多校(一) 一.比赛小结 二.题目分析及解法(基础题) 1001.String 1002.Dragon slayer 1003.BackPack 1004 ...

最新文章

  1. MOS管电源开关电路的软启动
  2. VC中BSTR和CString的使用
  3. Flask的多app应用,多线程如何体现
  4. C++ 通讯录管理系统实验报告
  5. Hudi on Flink 快速上手指南
  6. ucinet计算聚类系数大于1怎么办_ucinet使用说明技巧.ppt
  7. Python爬虫教程:网易云音乐歌词
  8. html是乱码怎么解决,如何解决html乱码问题
  9. 如何申请注册微软邮箱(支持海外apple ID注册)亲测
  10. 电驴找不到服务器,电驴怎么连接服务器?电驴连接不上服务器的解决方法介绍...
  11. raster包—crop函数
  12. angular中自定义组件实现双向绑定
  13. 9大论坛、多项AI创新成果,Imagination邀您共聚 AIIA2020人工智能开发者大会
  14. PLC模拟量输出 模拟量输出FB(FX3U连接FX2N-2DA)
  15. 新电脑安装python环境
  16. 新code为aadb010476_【AACA建筑师评估】职业评估说明
  17. Android漏洞扫描工具Code Arbiter
  18. 论文阅读:人机情绪的趋同、循环与溢出——基于 Twitter 涉中议题的数据分析
  19. 火车头采集器V9版本 Json提取bug
  20. python淘课之家_python练习——moudule03——选课系统

热门文章

  1. Latex:简介及安装
  2. vue 组件全局封装_vue组件封装共用的方法
  3. Mycat读写分离的简单实现
  4. CNNFeatures Off-the-Shelf: An Astounding Baseline for Recognition
  5. eclipse查看代码git历史_Eclipse中GIT历史版本比较和回退
  6. 微信公众号广告平台服务器,微信公众号的与众不同,从第三方平台开始
  7. 连接佛山西站和白云机场,广佛环线城际铁路也有新消息…
  8. pandas调用mysql数据库字段注释快速更改列名,MySQL的注释来当列名
  9. 【特征提取】Hog特征原理简介与代码实践
  10. 爱奇艺在文本舆情挖掘上的技术探索和实践