【USACO】numtri
给一颗数字树,让找一条数字和最大的路径。一下子就想起刚学不久的回溯法了。照着写了个代码,调了调搞通了。在小数据的情况下是对的,但是在test 6 树有199层的时候溢出了。
#include <stdio.h>
int BackTrack(int n, int (*num)[], int * summax) //回溯法
{
*summax = ;
int sum = ;
int k = ;
int S[] = {};
int sign[] = {};
int sumn[] = {}; //保存算到第k行的和
S[k] = ;
sign[k] = ;
do{
while(S[k] != )
{
if(S[k] == && k != )
{
sign[k]++; //选择右边的数
}
if(k == )
{
sumn[k] = num[k][sign[k]];
}
else
{
sumn[k] = sumn[k - ] + num[k][sign[k]];
}
S[k]--;
if(k < n - )
{
k++;
S[k] = ; //新到一行时 共有两个选择
sign[k] = sign[k - ] + - S[k]; //选择左边的数
}
else
{
if(sumn[k] > *summax)
{
*summax = sumn[k];
} }
}
k--;
}while(k > );
return ;
} int main()
{
FILE *in, *out;
in = fopen("numtri.in", "r");
out = fopen("numtri.out", "w"); int N;
int num[][];
int summax;
int i, j;
fscanf(in, "%d", &N);
for(i = ; i < N; i++)
{
for(j = ; j <= i; j++)
{
fscanf(in, "%d", &num[i][j]);
}
} BackTrack(N, num, &summax);
fprintf(out, "%d\n", summax); return ;
}
-------------------------------------------------------------
针对回溯法溢出,很容易想到的是计算有冗余。举例来说: 在计算5的分支时,其实下面7的情况已经在之前都算过了的,只要知道7 和 8哪个数对应的下面的和最大就好了。
3
4 5
6 7 8
9 10 11 12
于是可以换成从下到上的解法,从最底下开始计算在每一层对应位置上和最大的数,最下面一层就是数本身,再往上每次都是 数本身 + max(下一行左边最大求和数, 下一行右边最大求和数), 在最高层时输出最大值。写完代码后很奇怪,自己的电脑上跑总是溢出,但在测评系统上却AC了。
#include <stdio.h> int max(int a, int b)
{
return a > b ? a : b;
} int tmp[] = {}; //每层用同一个tmp存储最大值就好了,因为在计算出高层的最大值后,低层的最大值就没有用了。
int downtotop(int c, int N, int (*num)[])
{
int i;
if(c == N)
{
if(c != )
{
for(i = ; i < c; i++)
{
tmp[i] = num[c - ][i];
}
downtotop(c-, N, num);
}
else //针对只有一个数的情况
{
return num[][];
}
}
else
{
for(i = ; i < c; i++)
{
tmp[i] = num[c - ][i] + max(tmp[i], tmp[i + ]);
}
if(c == )
{
return tmp[];
}
else
{
downtotop(c-, N, num);
}
}
} int main()
{
FILE *in, *out;
in = fopen("numtri.in", "r");
out = fopen("numtri.out", "w"); int N;
int num[][];
int summax;
int i, j;
fscanf(in, "%d", &N);
for(i = ; i < N; i++)
{
for(j = ; j <= i; j++)
{
fscanf(in, "%d", &num[i][j]);
}
} summax = downtotop(N, N, num);
fprintf(out, "%d\n", summax); return ;
}
-------------------------------------------
经过好友点拨,发现是int num[1000][1000]太大了,超过了栈内存,必须动态分配。改好后自己在电脑上也跑通了。在测评系统上消耗的内存也小了。
int i;
int N;
fscanf(in, "%d", &N); int **num = (int **)malloc( * sizeof(int *));
for(i = ; i < N; i++)
{
num[i] = (int *)malloc( * sizeof(int));
}
--------------------------------------
看了答案还是想复杂了 不需要递归的 直接for循环就好
for (i = ; i < rows; i++)
res[i] = tri[rows-][i]; for (i = rows-; i > ; i--)
for (j = ; j <= i; j++)
res[j] = tri[i-][j] + max(res[j],res[j+]);
-----------------------------------
答案还有一种从上到下的思路,不用先把数字存下来,可以取一个计算一步。如同从上到下,每次有两个选择,从下到上每次也是两个选择(边上的只有一个选择),从上往下加时可以只选择两个上方已有数字钟最大的,最后可以得到最下方N个最大值,选出其中最大的一个即可。
for(i=; i<=r; i++) {
memmove(oldbest, best, sizeof oldbest);
for(j=; j<i; j++) {
fscanf(fin, "%d", &n);
if(j == )
best[j] = oldbest[j] + n;
else
best[j] = max(oldbest[j], oldbest[j-]) + n;
}
}
【USACO】numtri的更多相关文章
- POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)
POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...
- 1642: 【USACO】Payback(还债)
1642: [USACO]Payback(还债) 时间限制: 1 Sec 内存限制: 64 MB 提交: 190 解决: 95 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 &quo ...
- 1519: 【USACO】超级书架
1519: [USACO]超级书架 时间限制: 1 Sec 内存限制: 64 MB 提交: 1735 解决: 891 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 Farmer Jo ...
- Java实现【USACO】1.1.2 贪婪的礼物送礼者 Greedy Gift Givers
[USACO]1.1.2 贪婪的礼物送礼者 Greedy Gift Givers 题目描述 对于一群要互送礼物的朋友,你要确定每个人送出的礼物比收到的多多少(and vice versa for th ...
- 【CPLUSOJ】【USACO】【差分约束】排队(layout)
[题目描述] Robin喜欢将他的奶牛们排成一队.假设他有N头奶牛,编号为1至N.这些奶牛按照编号大小排列,并且由于它们都很想早点吃饭,于是就很可能出现多头奶牛挤在同一位置的情况(也就是说,如果我们认 ...
- 【USACO】Dining
[题目链接] [JZXX]点击打开链接 [caioj]点击打开链接 [算法] 拆点+网络流 [代码] #include<bits/stdc++.h> using namespace std ...
- 【USACO】Optimal Milking
题目链接 : [POJ]点击打开链接 [caioj]点击打开链接 算法 : 1:跑一遍弗洛伊德,求出点与点之间的最短路径 2:二分答案,二分”最大值最小“ 3.1:建边,将 ...
- 【USACO】 Balanced Photo
[题目链接] 点击打开链接 [算法] 树状数组 [代码] #include<bits/stdc++.h> using namespace std; int i,N,ans,l1,l2; ] ...
- 【USACO】 Balanced Lineup
[题目链接] 点击打开链接 [算法] 这是一道经典的最值查询(RMQ)问题. 我们首先想到线段树.但有没有更快的方法呢?对于这类问题,我们可以用ST表(稀疏表)算法求解. 稀疏表算法.其实也是一种动态 ...
随机推荐
- GitHub 优秀的 Android 开源项目
转自:http://blog.csdn.net/shulianghan/article/details/18046021 主要介绍那些不错个性化的View,包括ListView.ActionBar.M ...
- 【BZOJ-1965】SHUFFLE 洗牌 快速幂 + 拓展欧几里德
1965: [Ahoi2005]SHUFFLE 洗牌 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 541 Solved: 326[Submit][St ...
- PS图层混合模式实例详解
PS中的很多概念都和Core Graphics中的概念相通,比如蒙版.路径.裁剪.混合模式等等.如果你对Core Graphics中的混合模式不太理解,阅读本篇文章能让你对Core Gra ...
- 软件开发过程中的审查 (Review)
http://blog.csdn.net/horkychen/article/details/5035769 软件开发过程中的审查 (Review) 希望别人做些什么->定义出流程 希望别人 ...
- Linux VPS新硬盘分区与挂载教程
通过fdisk -l我们可以看到/dev/xvdb(此名称因系统而异)容量有23.6G,而且没有分区,接下来我们对它进行分区和挂载 (红色字为需要输入的部分,黑色字为系统显示部分) 1.fdisk - ...
- POI读写Excel简述之读取
一.POI读取Excel文件(以Excel2003版为例,2007版就是根据文件扩展名xlsx将HSSFWorkbook换为XSSFWorkbook,及其Sheet.Row.Cell也相应替换) // ...
- phpcms 采集教程
Phpcms网站管理系统目前最新版本为Phpcms v9,作为国内主流CMS系统之一,目前已有数万网站的应用规模.那么其自带的采集模块功能如何呢,来看看吧. 文章采集 Phpcms v9默认内置有文章 ...
- ios开发 网络编程浅析(一)
iphone包含了很多框架和库,从底层的套接字到不同层次的封装,可以方便地给程序添加网络功能. (1)BSD套接字.最底层的套接字,这是Unix网络开发常用的API.如果从其他系统移植程序,而程序用的 ...
- Log4Net日志记录两种方式
简介 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具. log4net是Ap ...
- linux的设置ip连接crt,修改主机名,映射,建文件
1.修改IP(或者vim vi /etc/sysconfig/network-scripts/ifcfg-eth0) 2.连接 crt 3.修改主机名 用vim 编辑 /etc/sysconfig/n ...