当前位置:首页 >> 半导体技术突破 >> 【VIJOS - P1037】搭建双塔(dp),中兴nubia z5 mini手机

【VIJOS - P1037】搭建双塔(dp),中兴nubia z5 mini手机

cpugpu芯片开发光刻机 半导体技术突破 2
文件名:【VIJOS - P1037】搭建双塔(dp),中兴nubia z5 mini手机 【VIJOS - P1037】搭建双塔(dp)

题干:

描述

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 样例输入1 51 3 4 5 2

Copy

样例输出1 7

Copy

来源

某校NOIP模拟题

解题报告:

非常巧妙的dp题,类似于背包,dp[i][j]表示前i块木块,高块和低块的差值为j时,最低的木块的最大高度。(其实维护的是最高的木块的最大高度也可以)

注意判断无解是<=0而不是<0。因为一直不选木块也可以成功转移到dp[n][0]只是值为0)。

AC代码:

#include<cstdio>#include<iostream>#include<algorithm>#include<queue>#include<stack>#include<map>#include<vector>#include<set>#include<string>#include<cmath>#include<cstring>#define FF first#define SS second#define ll long long#define pb push_back#define pm make_pairusing namespace std;typedef pair<int,int> PII;const int INF = 0x3f3f3f3f;const int MAX = 100 + 5;int n;int dp[MAX][5555];int a[MAX];int main(){cin>>n;memset(dp,-INF,sizeof dp);dp[0][0] = 0;for(int i = 1; i<=n; i++) cin>>a[i];for(int i = 1; i<=n; i++) {for(int j = 0; j<=2004; j++) {dp[i][j] = max(dp[i][j],dp[i-1][j]);//第i块砖不放if(j>=a[i])dp[i][j] = max(dp[i][j],dp[i-1][j-a[i]]);//放在高的上 dp[i][j] = max(dp[i][j],dp[i-1][j+a[i]]+a[i]);//放在矮的上且没超过高塔if(a[i]>=j)dp[i][j] = max(dp[i][j],dp[i-1][a[i]-j]+(a[i]-j));}}int ans = dp[n][0];if(ans > 0) printf("%d\n",ans);else printf("Impossible\n");return 0 ;}/*21 3*/

如果要维护最高高度的话就这样转移:

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接