【cqbzoj1510】 遇见 滚动数组 dp 解题报告
来源:互联网 发布:mysql 按月查询 编辑:程序博客网 时间:2024/06/08 11:58
遇见
时间限制: 1 Sec 内存限制: 64 MB
题目描述
燕姿在桥的这一端,而xx在桥的另一端。这座桥非常特殊,桥面是由2N-1个方格组成的,每个方格里写有一个数码Ai(-50<=Ai<=50)。如下是N=4时的情况。可以认为燕姿从最下面出发。每一次,她可以向上跳到与自己所在方格相临的其中一个方格内(例如在最下面的7中,可以跳到上一行的10和8中)。当燕姿跳到最顶端的方格后,她就不能再移动了。(在未到顶端前,不允许跳到表格外。)每在一格内,都要把格内的数字写下来。 但是,仅仅到达顶端是不够的。桥会向对岸的xx询问一个数字k,燕姿到达顶端后,拿出写下来的数字,可以在任意两个数字间添加“+”或“-”号,使得计算的结果m最接近k。经过桥的判断,如果对于桥上的方格m是最接近k的数字,那么燕姿就可以通过桥和xx相遇,否则……… (为了让燕姿能更容易地通过,xx给出的数字总是0)你的任务,就是帮助燕姿找出这个最接近k的m.
输入
输入的第一行是N(1<=N<=30),接下来2N-1行给出了表格中每行的每个方格中的数字,第i+1行的第j个数字对应于表格中第i行的第j个数字。文件中第二行的数字表示的是表格顶端的方格中的数字。所有的数字都是整数,同一行相邻的两个数字间用空格符隔开。
输出
输出只有一行,是你所求出的最接近零的计算结果的绝对值
样例输入
4
2
3 1
-3 5 7
6 10 -2 20
-7 -5 -8
10 8
7
样例输出
0
提示
最优解7+8+(-5)+(-2)-5-1-2=0
或7+10+(-7)-6+(-3)-3+2=0
或7+10+(-5)-10-5+1+2=0
或+10+(-5)+(-2)-5-3-2=0
解题报告
一道dp题
设inp[i][j]为桥上i行j列的数字
设
那么有大约形如
的递推式
是不是感觉和背包比较像呢~
在不同情况下有轻微变更
但是f数组过于巨大肯定是开不下的,
发现递推的一维最多用到i和i-1,
于是可以使用滚动数组节约空间
那么变成
每次把f[i&1]memset清空就可以了
接下来是具体的代码实现
#include<cstring>#include<cstdio>const int MAXN=35;inline int min(const int &a,const int &b){return a>b?b:a;}int inp[MAXN<<1][MAXN];bool f[2][MAXN][3100];int main(){ int n; scanf("%d",&n); scanf("%d",&inp[1][1]); f[1][1][1500+inp[1][1]]= f[1][1][1500-inp[1][1]]=true; for(int i=2;i<=n;i++){ memset(f[i&1],0,sizeof f[i&1]); for(int j=1;j<=i;j++){ scanf("%d",&inp[i][j]); for(int k=50;k<=2950;k++) f[i&1][j][k]= f[!(i&1)][j][k+inp[i][j]]|| f[!(i&1)][j][k-inp[i][j]]|| f[!(i&1)][j-1][k+inp[i][j]]|| f[!(i&1)][j-1][k-inp[i][j]]; } } int t; for(int i=n-1;i>=1;i--){ memset(f[i&1],0,sizeof f[i&1]); for(int j=1;j<=i;j++){ scanf("%d",&t); for(int k=50;k<=3000;k++) f[i&1][j][k]= f[!(i&1)][j][k+t]|| f[!(i&1)][j][k-t]|| f[!(i&1)][j+1][k+t]|| f[!(i&1)][j+1][k-t]; for(int k=0;k<50 ;k++) f[i&1][j][k]|= f[!(i&1)][j][k+t]|| f[!(i&1)][j+1][k+t]; } } int u,d; for(u=1500;u<=3000;u++) if(f[1][1][u])break; for(d=1500;d>=0;d--) if(f[1][1][d])break; int ans=min(u-1500,1500-d); printf("%d\n",ans);}
- 【cqbzoj1510】 遇见 滚动数组 dp 解题报告
- Monkey and Banana(HDU 1069)解题报告(DP - 滚动数组)
- BZOJ 1264 树状数组+DP 解题报告
- BZOJ 1227 DP+树状数组 解题报告
- BZOJ 3688 树状数组优化DP 解题报告
- 【DP】2479解题报告
- HDU1864解题报告-dp
- HDU4089概率dp解题报告
- hdu 1024 dp 解题报告
- 解题报告:HDU_3944 DP? 数论
- 解题报告: POJ_2955 Brackets DP
- Poj 1260 DP 解题报告
- POJ 1260 DP解题报告
- POJ 1160 DP 解题报告
- BZOJ 1820 DP 解题报告
- BZOJ 1566 DP 解题报告
- 解题报告:LightOJ_1406 状压DP
- 2017.10.4 DP 解题报告
- Educational Codeforces Round 15
- program files文件夹和program files(x86)文件夹
- 排序算法之选择排序
- Android中asset文件夹和res/raw文件夹区别
- unique path II 动态规划 用一位数组完成
- 【cqbzoj1510】 遇见 滚动数组 dp 解题报告
- C语言指针总结
- 暑期工作日志-Day19
- 我的反思之路
- tjut 3573
- 网易校园招聘2017编程题--回文数问题
- Spring1.基础知识
- oracle拆分逗号分隔字符串 实现split
- Android基础之如何在AS中导入jniLibs目录