vijos1037搭建双塔(一维背包问题)
描述
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”。
来源
某校NOIP模拟题
很容易地敲出了暴力代码
j=dfs(l1,l2,cur)
{
if cur==n+1
if l1==l2 then record(l1)
exit
dfs(l1+h[cur],l2,cur+1)
dfs(l1,l2+h[cur],cur+1)
dfs(l1,l2,cur+1)
}
于是自己愚蠢地写了一个动规代码
dp()
for(i->1 to n)
for(j->tot/2 to h[i])
f[i][j]=f[i-1][j]
if(f[i-1][j-h[i]])
if f[i-1][j] then record(j)
f[i][j]=1
然而思路是错的,得分:30。
测试数据 #0: Accepted, time = 0 ms, mem = 516 KiB, score = 10
测试数据 #1: WrongAnswer, time = 0 ms, mem = 516 KiB, score = 0
测试数据 #2: WrongAnswer, time = 15 ms, mem = 516 KiB, score = 0
测试数据 #3: WrongAnswer, time = 0 ms, mem = 512 KiB, score = 0
测试数据 #4: Accepted, time = 0 ms, mem = 520 KiB, score = 10
测试数据 #5: WrongAnswer, time = 0 ms, mem = 516 KiB, score = 0
测试数据 #6: WrongAnswer, time = 0 ms, mem = 516 KiB, score = 0
测试数据 #7: Accepted, time = 0 ms, mem = 516 KiB, score = 10
测试数据 #8: WrongAnswer, time = 0 ms, mem = 516 KiB, score = 0
测试数据 #9: WrongAnswer, time = 0 ms, mem = 512 KiB, score = 0
WrongAnswer, time = 15 ms, mem = 520 KiB, score = 30
标准解法:令f[i][j]为前i块水晶搭成的双塔高度差为j时,最矮的塔的高度的max值。
为转移f[i][j],我们先列出一下策略:
1.不选该水晶块,此时直接继承,f[i][j]->f[i-1][j],此时的高度不变
2.选择该水晶块,放在原本就高的塔上,f[i][j]=f[i-1][j-h[i]]
3.选择该水晶块,放在原本就小的塔上,则:
(1.小的还是小的,那么f[i][j]=f[i-1][j+h[i]]+h[i]
(2.小的成为了大的,那么f[i][j]=f[i-1][h[i]-j]+h[i]-j
Qed!
代码:
|
100
|
0 | 536 | ksq2013 | C++ | 2016-08-18 22:36:20 |
#include<stdio.h>
#include<stdlib.h>
using namespace std;
inline int mx(int x,int y)
{
if(x>y)return x;
return y;
}
int f[][];
int n,h[],tot;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&h[i]);
tot+=h[i];
}
for(int i=;i<=;i++)
for(int j=;j<=tot;j++)
f[i][j]=-0x3f3f3f3f;
int t=;
for(int i=;i<=n;i++){
t^=;
for(int j=h[i];j<=tot;j++)
f[t][j]=mx(f[t][j],f[^t][j-h[i]]);
for(int j=;j<=tot-h[i];j++)
f[t][j]=mx(f[t][j],f[^t][j+h[i]]+h[i]);
for(int j=;j<h[i];j++)
f[t][j]=mx(f[t][j],f[^t][h[i]-j]+h[i]-j);
for(int j=;j<=tot;j++)
f[^t][j]=f[t][j];
}
if(f[^t][])
printf("%d\n",f[^t][]);
else puts("Impossible");
return ;
}
其实这样写更直观
#include<iostream>
using namespace std;
int n,h[],tot;
bool f[][];
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=;i<=n;i++)
cin>>h[i],
tot+=h[i];
f[][]=;
tot>>=;
for(int k=;k<=n;k++)
for(int i=tot;i>=;i--)
for(int j=tot;j>=;j--){
if(i-h[k]>=&&f[i-h[k]][j])f[i][j]=;
else if(j-h[k]>=&&f[i][j-h[k]])f[i][j]=;
}
for(int i=tot;i>=;i--)
if(f[i][i]){
cout<<i<<endl;
return ;
}
cout<<"Impossible"<<endl;
return ;
}
vijos1037搭建双塔(一维背包问题)的更多相关文章
- vijos P1037搭建双塔
P1037搭建双塔 Accepted 标签:动态规划 背包 描述 2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难.为了纪念“9?11”事件, ...
- vijosP1037搭建双塔
vijosP1037搭建双塔 链接:https://vijos.org/p/1037 [思路] DP. [代码] #include<iostream> #include<cstrin ...
- tyvj1114 搭建双塔
描述 2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难.为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔. Mr. F有 ...
- VIJOS P1037搭建双塔[DP]
描述 2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难.为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔. Mr. F有N块水晶,每块 ...
- 搭建双塔(vijos 1037)
描述 2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难.为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔. Mr. F有N块水晶,每块 ...
- 【动态规划】Vijos P1037 搭建双塔
题目链接: https://vijos.org/p/1037 题目大意: 给n块砖的长度(n<=100),问从中任选m块砖能否建成2个相同高度的塔. 能的话求最高高度,不能输出 Impossib ...
- 备战NOIP每周写题记录(一)···不间断更新
※Recorded By ksq2013 //其实这段时间写的题远远大于这篇博文中的内容,只不过那些数以百记的基础题目实在没必要写在blog上; ※week one 2016.7.18 Monday ...
- dp式子100个……
1. 资源问题1-----机器分配问题F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2. 资源问题2------01背包问题F[I,j]:=max(f[i- ...
- dp方程
1. 资源问题1 -----机器分配问题 F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2. 资源问题2 ------01背包问题 F[I,j]:=ma ...
随机推荐
- 腾讯bugly 的crash 上报和umeng的比较
说到crash上传工具,大家肯定会第一时间想到umeng,不错,umeng 是最早推出 crash 上报的工具之一,在刚推出来的时候,特别受到ios开发人员的喜爱. 因为个时候,内存是手动管理的,很容 ...
- Android之滑屏动画和自定义控件
滑屏动画 在Android系统中,通过手势识别切换界面时,通常会在界面切换时加入动画,以提高用户的体验效果,这种动画一般都采用平移动画,下一个界面进入时,上一个界面移除屏幕. 图中标识的均为左上角坐标 ...
- Android项目实战(十七):QQ空间实现(二)—— 分享功能 / 弹出PopupWindow
这是一张QQ空间说说详情的截图. 分析: .点击右上角三个点的图标,在界面底部弹出一个区域,这个区域有一些按钮提供给我们操作 .当该区域出现的时候,详情界面便灰了,也说成透明度变化了 .当任意选了一个 ...
- 关于OC中的block自己的一些理解(一)
一.关于block 1.block的作用:保存一段代码. 2.苹果官方推荐的一种语法,类似于C语言的函数,但是比函数更加灵活. 3.^是block语法的标识. 二.block的用法 1)无返回值无参数 ...
- socket编程中客户端常用函数 以及简单实现
1 常用函数 1.1 connect() int connect(int sockfd, const struct sockaddr *servaddr, socklen_taddrlen); 客 ...
- IOS开发之自动布局--VFL语言
前言:VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言.对于纯代码发烧友,值得我们去学习和了解哦. 1.什么是VFL语言 VFL全称是Visual Format Language,翻 ...
- 开源游戏 “Elvish Bird”
简介: 这个游戏是我在今年(2014/03)课余时闲着无聊做的一个冒险类小游戏,总共花了5个工作日才完成,为了游戏的效率,做了很多优化,目前在IE8以上浏览器能够流畅运行,运行时如果屏幕分辨率不兼容, ...
- 浅谈JS中的继承
前言 JS 是没有继承的,不过可以曲线救国,利用构造函数.原型等方法实现继承的功能. var o=new Object(); 其实用构造函数实例化一个对象,就是继承,这里可以使用Object中的所有属 ...
- git技巧记录--子模块删除方法
把子模块推进去了,删掉吧(将子模块删除,然后提交推送),删除子模块步骤: 1.在Platform.Web库下,右键->Git Bash,进入git命令行窗口,输入:git rm –-cached ...
- goldengate初始化
对丢弃已久的goldengate环境重新配置,使其重新开始跑起来 环境是一个主机上的两个库,都是单机,所以也就没配pump进程了,trail file都是在一个文件夹下的,extract写trail ...