Little Charlie is a nice boy addicted to candies. He is even a subscriber to All Candies Magazine and was selected to participate in the International Candy Picking Contest.

In this contest a random number of boxes containing candies are disposed in M rows with N columns each (so, there are a total of M × N boxes). Each box has a number indicating how many candies it contains.

The contestant can pick a box (any one) and get all the candies it contains. But there is a catch (there is always a catch): when choosing a box, all the boxes from the rows immediately above and immediately below are emptied, as well as the box to the left and the box to the right of the chosen box. The contestant continues to pick a box until there are no candies left.

The figure bellow illustrates this, step by step. Each cell represents one box and the number of candies it contains. At each step, the chosen box is circled and the shaded cells represent the boxes that will be emptied. After eight steps the game is over and Charlie picked 10+9+8+3+7+6+10+1 = 54 candies.

For small values of M and N, Charlie can easily find the maximum number of candies he can pick, but when the numbers are really large he gets completely lost. Can you help Charlie maximize the number of candies he can pick?

Input

The input contains several test cases. The first line of a test case contains two positive integers M and N (1 ≤ M×N ≤ 105 ), separated by a single space, indicating the number of rows and columns respectively. Each of the following M lines contains N integers separated by single spaces, each representing the initial number of candies in the corresponding box. Each box will have initially at least 1 and at most 103 candies. The end of input is indicated by a line containing two zeroes separated by a single space

Output

For each test case in the input, your program must print a single line, containing a single value, the integer indicating the maximum number of candies that Charlie can pick

Sample Input

5 5

1 8 2 1 9

1 7 3 5 2

1 2 10 3 10

8 4 7 9 1

7 1 3 1 6

Sample Output

54

水dp

一开始觉得n m的范围很大,仔细一看才知道n*m<=100000。。。。

我们可以每一行进行一次dp得到这一行的最大值  构造数组 a  然后对a数组在进行一次dp.

横着dp和竖着dp的状态转移是一样的   dp[i]=max(dp[i-1],dp[i-2]+a[i])   即前i个数能得到的最大值

/* ***********************************************
Author :guanjun
Created Time :2016/10/7 12:08:19
File Name :la4212.cpp
************************************************ */
#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define mod 90001
#define INF 0x3f3f3f3f
#define maxn 10010
#define cle(a) memset(a,0,sizeof(a))
const ull inf = 1LL << ;
const double eps=1e-;
using namespace std;
priority_queue<int,vector<int>,greater<int> >pq;
struct Node{
int x,y;
};
struct cmp{
bool operator()(Node a,Node b){
if(a.x==b.x) return a.y> b.y;
return a.x>b.x;
}
}; bool cmp(int a,int b){
return a>b;
}
vector<int>v[];
int dp[];
int a[];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
//freopen("out.txt","w",stdout);
int n,m,x;
while(cin>>n>>m){
if(n==&&m==)break;
for(int i=;i<=n;i++){
v[i].clear();
for(int j=;j<=m;j++){
scanf("%d",&x);
v[i].push_back(x);
}
}
//先横着dp 再竖着dp
cle(a);
for(int i=;i<=n;i++){
m=v[i].size();
cle(dp);
for(int j=;j<m;j++){
if(j<)dp[j]=max(dp[j-],v[i][j]);
else dp[j]=max(dp[j-]+v[i][j],dp[j-]);
}
//cout<<"hang "<<dp[m-1]<<endl;
a[i]=dp[m-];
}
//for(int i=1;i<=n;i++)cout<<a[i]<<endl;
cle(dp);
for(int i=;i<=n;i++){
if(i<=)dp[i]=max(dp[i-],a[i]);
else dp[i]=max(dp[i-]+a[i],dp[i-]);
}
if(n==)cout<<max(dp[],dp[])<<endl;
else cout<<dp[n]<<endl;
}
return ;
}

更新:2018.6.15

/* ***********************************************
Author :guanjunace@foxmail.com
Created Time :2018年06月15日 星期五 09时59分17秒
File Name :131.cpp
************************************************ */
#include <iostream>
#include <vector>
using namespace std; int solve(vector<int>& a) {
int len = a.size();
vector<int> dp(len, );
dp[] = a[];
for (int i = ; i < len; ++i) {
if (i >= ) dp[i] = max(dp[i-] + a[i], dp[i-]);
else dp[i] = max(a[i-], a[i]);
//cout << dp[i] << "-" << endl;
}
return dp[len - ];
} int main() {
int n, m, x;
while (cin >> n >> m && n && m) {
vector<int> v;
for (int i = ; i < n; ++i) {
vector<int> a;
for (int j = ; j < m; ++j) {
cin >> x;
a.push_back(x);
}
//cout << solve(a) << endl;
v.push_back(solve(a));
}
cout << solve(v) << endl;
}
return ;
}

UVALive 4212 - Candy的更多相关文章

  1. UVALive 5791 Candy's Candy 解题报告

    比赛总结 题目 题意: 有f种口味的糖果,现在要把每颗糖果分到一些packs里面去.packs分两种: flavored pack:只有一种口味. variety pack:每种口味都有. 求满足下列 ...

  2. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  3. [LeetCode] Candy 分糖果问题

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  4. UVALive - 4108 SKYLINE[线段树]

    UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug ...

  5. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

  6. Leetcode Candy

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  7. LeetCode 135 Candy(贪心算法)

    135. Candy There are N children standing in a line. Each child is assigned a rating value. You are g ...

  8. [LeetCode][Java]Candy@LeetCode

    Candy There are N children standing in a line. Each child is assigned a rating value. You are giving ...

  9. 【leetcode】Candy(hard) 自己做出来了 但别人的更好

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

随机推荐

  1. JavaScipt30(第一个案例)(主要知识点:键盘事件以及transitionend)

    今天得到一个github练习项目,是30个原生js写成的小例子,麻雀虽小五脏俱全,现在记录一下第一个. 第一个是键盘按键时页面上对应的键高亮,同时播放音频,松开后不再高亮. 我自己实现了一下,然后查看 ...

  2. 关于iframe与$.load()哪个更好

    iframe与$.load()哪个更好       iframe可以直接加载页面,但是要付出降低搜索引擎搜索效率的代价,它引入静态文件的方式是完全独立的,简单意思就是,在页面一(父级页面)用ifram ...

  3. ThinkPHP---thinkphp会话支持和文件载入

    [一]会话控制 会话支持一般指cookie和session,在ThinkPHP里为了方便开发,封装了cookie和session方法. (1)session方法 在函数库封装了session方法 se ...

  4. 00Enterprise Resource Planning

    Enterprise Resource Planning         企业资源计划即 ERP (Enterprise Resource Planning),由美国 Gartner Group 公司 ...

  5. django在验证登录页面时遇到的数据查询问题

    数据库查询时针对不存在的用户名进行验证 django在查询数据库时,可以使用get和filter两种方法. 两者的区别 当数据库内不存在该数据时,get会返回异常,而filter会返回空. 当数据库内 ...

  6. 第三节:EF

    1.删除要进行判空 public ActionResult DelClassMethod(string gId) { //根据gId查询对应条目 var grade = oc.BllSession.I ...

  7. 洛谷——P3373 【模板】线段树 2&& B 数据结构

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 线段树维护区间乘法 1.如何 ...

  8. Cyclic Nacklace HDU - 3746 (kmp next数组应用)

    题目大意 给出字符串,寻找最小要补全的字符个数,使得字符串是两次的循环 解法 通过寻找规律,我们又发现了len-next[len]又派上了用场 ①如果next[len]是0,说明最大前缀后缀和为0,那 ...

  9. 总结在Linux终端中进行算术运算的6种方式

    1.使用bash 使用双括号可以像C语言一样直接使用运算符进行计算. +)) a=$((*)) echo $a b=$(($a-)) echo $b d=$(($b/)) echo $d e=$(($ ...

  10. LINUX-文件的特殊属性 - 使用 "+" 设置权限,使用 "-" 用于取消

    chattr +a file1 只允许以追加方式读写文件 chattr +c file1 允许这个文件能被内核自动压缩/解压 chattr +d file1 在进行文件系统备份时,dump程序将忽略这 ...