codefore 213 C Relay Race (朴素DP)

原题地址:http://codeforces.com/problemset/problem/213/C

题意:略

题解:dp,状态为点的位置,直接枚举复杂度是n4,利用两个点坐标之和之间的关系,优化到n3。

#include<bits/stdc++.h>

#define clr(x,y) memset((x),(y),sizeof(x))

using namespace std;
typedef long long LL;

const int maxn=300;
const int INF=1e8;

int A[maxn+5][maxn+5];
int dp[maxn+5][maxn+5];
int dx[]={-1,-1,0,0};
int dx2[]={-1,0,-1,0};

int n;

int main(void)
{
    #ifdef ex
    freopen ("../in.txt","r",stdin);
    //freopen ("../out.txt","w",stdout);
    #endif

    scanf("%d",&n);
    for (int i=1;i<=n;++i)
    {
        for (int j=1;j<=n;++j)
        {
            scanf("%d",&A[i][j]);
        }
    }

    int x1,y1,x2,y2,tmp;

    //cout<<dp[1][1][1]<<‘ ‘<<dp[2][1][1]<<endl;
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            dp[i][j]=-INF;

    dp[1][1]=A[1][1];
    for (int i=3;i<=2*n;++i)
    {
        for (int j=min(i-1,n);j>=1;--j)
        {
            for (int k=min(i-1,n);k>=1;--k)
            {
                int T=-INF;
                for (int q=0;q<=3;++q)
                {
                    x1=j+dx[q];
                    x2=k+dx2[q];
                    y1=i-1-x1;
                    y2=i-1-x2;

                    if (x1<=0 || x1>n || y1<=0 || y1>n) continue;
                    if (x2<=0 || x2>n || y2<=0 || y2>n) continue;

                    if (j==k) tmp=A[j][i-j];
                    else tmp=A[j][i-j]+A[k][i-k];

                    T=max(T,dp[x1][x2]+tmp);
                }
                dp[j][k]=T;
                //printf("%d %d %d %d\n",i,j,k,dp[j][k]);
            }
        }
    }

    int ans=dp[n][n];
    printf("%d\n",ans);
}
时间: 2024-10-18 15:12:03

codefore 213 C Relay Race (朴素DP)的相关文章

hoj_10001_朴素DP(LIS)

Longest Ordered Subsequence Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB Total submit users: 1937, Accepted users: 1621 Problem 10001 : No special judgement Problem description A numeric sequence of ai is ordered if a1 < a2 <

POJ 3162 Walking Race 树形DP+线段树

给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成为一段长度为n的数列 现在mm想要从这数列中选出一个连续的区间,要求这个区间的max-min<=m 输出最长的区间 做了一个下午 思路: 分成2个部分: 1.求出数列,即对于一棵树,求出每一个节点能到达的最远距离 2.对于这段数列,选出一个区间,使得区间的max-min<=m,并且使得区间长度尽量

hdu 4123 Bob’s Race(树形dp+RMQ)

题目链接:hdu 4123 Bob's Race 题目大意:一个城镇有N个住户,N-1条路连接两个住户,保证N个住户联通,M次询问,给定N条边的信息,包括连 接的住户序号以及路的长度.然后是M次询问,每次询问Q,要求找到最长的连续序号,使得Max(dis[i]) - Min(dis[i]) ≤ Q(l≤i≤r),输出最大的r-l+1.dis[i]为从第i个住户出发,不重复走过路能移动的最远距离. 解题思路:树形dp,通过两次dfs,第1次处理出每个节点中孩子节点移动的最长距离和第二长距离,第2次

POJ - 3162 Walking Race 树形dp 单调队列

POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这样的区间最长的长度? 一开始楞是没看懂题意,最讨厌这种四级题,这是在刁难我英语小能手(能用翻译的就不自己动手).而且这题感觉单调队列那里的处理更难一点,不过还是来说一说怎么树形dp取得最远距离,先画个简简单单丑丑的图 我们直接从1作为根节点开始dfs的话,可以处理1的最远距离,并且可以得出到其它节点

[POJ3162]Walking Race(DP + 单调队列)

传送门 题意:一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多? 求每个点到最远距离的点的距离可以用 computer 的方法. 至于第二问,可以跑一遍2个单调队列. 具体是固定左端点,右端点向右平移到最远,直到不能平移,再左端点向右平移一位.在这中间维护单调队列和更新 ans 最大值. 具体细节看代码 ——代码 1 #incl

POJ 3162 Walking Race 树形dp 优先队列

http://poj.org/problem?id=3162 题意 :  一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多? 每个点的最大距离和之前http://acm.hdu.edu.cn/showproblem.php?pid=2196这道题一样 (就是求每个子树的最长子链,次长子链,然后求经过父亲节点能达到的最大值,比较一

213. House Robber II (DP)

1 class Solution { 2 public int rob(int[] nums) { 3 int n = nums.length; 4 int[] res = new int[n]; 5 if(n == 0) return 0; 6 if(n == 1) return nums[0]; 7 if(n == 2) return Math.max(nums[0], nums[1]); 8 res[0] = nums[0]; 9 res[1] = Math.max(nums[0], nu

[BZOJ4709][JSOI2011]柠檬 决策单调性优化dp

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4709 我好弱啊QAQ,网上dalao们的题解根本看不懂啊,折腾了几个小时,有一点明白了. 首先要把朴素dp方程退出来. ①题目中说每次从序列的左右选一端取,但是如果你真的照着题目说的这样做我也不知道会怎么样.事实上很明显不管怎么取,最终答案都只跟划分出的是哪几个区间有关.所以不妨从左端开始取. ②如果取一个区间,区间第一个贝壳的大小和最后一个贝壳的大小不一样,那么很明显可以去掉第一个或最

【DP】最长不下降子序列问题(二分)

Description 给你一个长度为n的整数序列,按从左往右的顺序选择尽量多的数字并且满足这些数字不下降. Thinking 朴素dp算法:F[i]表示到第i位为止的最长不下降子序列长度 F[i]=max(F[j])+1,其中(j<i且a[j]<=a[i]) 时间复杂度:O(n2) 考虑维护一个队列g,用g[i]表示长度为i的最长不下降子序列结尾的最小值.根据g[i]的单调性,可以用二分查找的方法快速找到以当前数a[i]结尾的最长不下降子序列. Code 1 #include<cstd