学习笔记:vijos1037[差值dp] 自己也不知道怎么就搞出来了
2017-07-12 18:57
246 查看
描述
2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难。为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔。Mr. F有N块水晶,每块水晶有一个高度,他想用这N块水晶搭建两座有同样高度的塔,使他们成为一座双塔,Mr. F可以从这N块水晶中任取M(1≤M≤N)块来搭建。但是他不知道能否使两座塔有同样的高度,也不知道如果能搭建成一座双塔,这座双塔的最大高度是多少。所以他来请你帮忙。
给定水晶的数量N(1≤N≤100)和每块水晶的高度Hi(N块水晶高度的总和不超过2000),你的任务是判断Mr. F能否用这些水晶搭建成一座双塔(两座塔有同样的高度),如果能,则输出所能搭建的双塔的最大高度,否则输出“Impossible”。
格式
输入格式输入的第一行为一个数N,表示水晶的数量。第二行为N个数,第i个数表示第i个水晶的高度。
输出格式
输出仅包含一行,如果能搭成一座双塔,则输出双塔的最大高度,否则输出一个字符串“Impossible”。
样例1
样例输入15
1 3 4 5 2
样例输出1
7
来源
某校NOIP模拟题懵逼题解
哇,刚刚看到这个题好懵逼啊,看了一下数据范围,好像是2重循环…然后就想到在背包中加一个维度来维护两塔的差值,然后f[i][j]代表用前i个水晶,两塔差值为j时,所得到的最大高度.对于每一个i,都有三个决策:
1.放第i块水晶到高的一个塔上.
2.放第i块水晶到矮的塔上.
3.不放第i块水晶
于是就搞粗来方程啦~
但是我好像并不能写出了23333
嗯就是用以前的状态推出当前状态是比较困难的…于是小仙女般的我就想到用填表法啦~以当前状态出发,推出三种状态,填上三个数…
萌萌的代码:
#include<cstdio> #include<cstring> #define max(a,b) ((a)>(b)?(a):(b)) #define MAXN (100+5) #define MAXH (2000+5) #define MAXC (2000+5) #define INF (2000) int f[MAXN][2*MAXC];//f[i][j]means used i diamond && the (upper-lower) is j &&the higher hight is f[i][j] int a[MAXN]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=0;i<=n;i++) { for(int j=0;j<=MAXC;j++) { f[i][j]=-INF; } } f[0][0]=0; for(int i=0;i<=n;i++) { for(int j=MAXC;j>=0;j--) { // f[i][j]=f[i-1][j]; if(f[i][j]>=0)//从已知的状态向后推 { f[i+1][j]=max(f[i+1][j],f[i][j]);//不放 f[i+1][a[i+1]+j]=max(f[i+1][a[i+1]+j],f[i][j]+a[i+1]);//放在较高的塔上 if(a[i+1]>=j)//放在较低的塔上 { f[i+1][a[i+1]-j]=max(f[i+1][a[i+1]-j],(f[i][j]+a[i+1]-j));//两塔之差小于当前水晶,所以放了该水晶两塔的高低关系将对调 } else { f[i+1][j-a[i+1]]=max(f[i+1][j-a[i+1]],f[i][j]);//两塔之差大于当前水晶,即使放了该水晶,高低关系也不变,高的依然高,矮的依然矮(就像我穿上增高鞋也没有gjp高QAQ) } } } } /*for(int i=0;i<=n;i++) { printf("%d:\t",i); for(int j=0; j<=7;j++) { printf("%d\t",f[i][j]); } puts(""); }*/ int ans=0; for(int i=1;i<=n;i++) { ans=max(ans,f[i][0]);//要求两塔高度相等,即差值为0 } if(ans) printf("%d",ans); else printf("Impossible"); return 0; }
by 没有dalao们可爱的 Cansult
相关文章推荐
- 自己对Z-stack的架构一些理解(仅作学习笔记,有错误希望大家能指出来,初学Z-Stack菜鸟一只)
- bzoj1192(数学,真不知道自己怎么做出来的)
- java学习笔记,自己有时间就整理的,有错的地方请指出来
- 只学一点点:我的技术学习策略(虽然不赞同,但可以参考一下,针对不常用的技术可以这样,同时可以:寻找遁去的一,不用管别人怎么想;有学习的时间,不如自己写、自己实践,否则学完了都不知道是什么东西)
- 给些网络视频教学也行啊 请教高手给我指点下 要买书也不不知道买什么好 我一点基础都没有 但不知道怎么学 我想学习C语言 谢谢了
- 不知道怎么了,突然想要写点什么出来
- 郁闷中.不知道怎么保存自己的文章不能被外部访问?
- wpf学习笔记(1)《都是自己根据网络资源学习记录的仅供参考》
- XAML!我所不知道的(学习笔记)
- 大家知道苍月((蒼ざめた月の光)苍青色的月光)在XP下怎么玩吗动不动就自己退出来
- 不知道在哪看的,感觉有点像自己的体会,自己修改了一点发出来
- 真正开始学习,asp.net了,可是不知道怎么在新闻首页添加可以滚动的新闻条。
- [学习笔记]Java代码构建一个线程池的自己学习写的实例,用这个你会更好的理解文章内容
- Ubuntu 学习笔记 - 继续背叛自己,直到离自己更近... - C++博客
- 上网的时候不知道自己电脑的IP地址怎么办? 找藏拙IP搜索
- 走上软件之路,以后就在这里记录自己的学习过程了(2007.12.18笔记)
- 郁闷中.不知道怎么保存自己的文章不能被外部访问?
- 今天心情不错,对CDocManager和CWinApp作了一点粗劣的学习,写出来勉励自己。
- wpf学习笔记(2)《都是自己根据网络资源学习记录的仅供参考》
- J2ME学习笔记(7)-- 如何在WKT中设置自己的工程目录