首页 > 其他分享 >CF213C (棋盘dp的经典例题)

CF213C (棋盘dp的经典例题)

时间:2023-05-08 20:23:50浏览次数:46  
标签:CF213C ch int max tot 例题 dp define

Relay Race - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

本题是棋盘dp的经典例题。

可以先转化一下题意:从(1,1)走两条路径到(n,n),再确保两人是同步行走的。

我们可以让一人的走路范围一直在左下方向,一人的走路范围一直在右上方向。(倘若两人的路径交叉,则都可以转化成这种情况)

令dp[i][j][k][l] 表示 第一个人走到(i,j) 第二个人走到(k,l) 能获得最大的值.但这空间复杂度会爆炸

注意到 i+j=k+l (因为是两人是同步的,时间一样)

令 i+j=k+l=tot

则 dp[tot][i][k]表示第一个人走到(i,tot-i),第二个人走到(k,tot-k)能获得的最大的值

dp转移:考虑dp[tot][i][j]从何转移过来(此时为走到(i,tot-i)和(j,tot-j))

如果 i==j,此时走到同一个点,此点的贡献只能算一次要特判:

dp[tot][i][j]=max({dp[tot-1][i][j],dp[tot-1][i-1][j],dp[tot-1][i][j-1],dp[tot-1][i-1][j]})+a[i][j];

否则两人便是走到不同的点,各自贡献答案:

dp[tot][i][j]=max(dp[tot][i][j],dp[tot-1][i][j]+a[i][tot-i]+a[j][tot-j]);

dp[tot][i][j]=max(dp[tot][i][j],dp[tot-1][i-1][j]+a[i][tot-i]+a[j][tot-j]);

dp[tot][i][j]=max(dp[tot][i][j],dp[tot-1][i][j-1]+a[i][tot-i]+a[j][tot-j]);

dp[tot][i][j]=max(dp[tot][i][j],dp[tot-1][i-1][j-1]+a[i][tot-i]+a[j][tot-j]);

 第一维可以滚动数组来优化空间复杂度,记得要及时更新不合法的状态。

初始化:dp[0][1][1]=a[1],(原本是dp[2][1][1]=a[1],但是滚动数组要%2),其余都为-INF

答案:dp[2*n%2][n][n]

Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
const int N=310;
//const int M=;
//const int inf=1e9;
const ll INF=1e18;
int T,n,a[N][N];
ll dp[3][N][N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
//    ios::sync_with_stdio(0);
//    cin.tie(0); 
    n=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) a[i][j]=read();
    for(int i=0;i<2;i++)
        for(int j=0;j<=n;j++)
            for(int k=0;k<=n;k++)
                dp[i][j][k]=-INF;
    dp[0][1][1]=a[1][1];
    for(int tot=3;tot<=2*n;tot++)
    {
        for(int i=1;i<=tot-1;i++)
            for(int j=1;j<=tot-1&&j<=i;j++)
            {
                //走到a[i][tot-i]和a[j][tot-j] 
                if(i==j) dp[tot%2][i][j]=max({dp[(tot-1)%2][i-1][j],dp[(tot-1)%2][i][j-1],dp[(tot-1)%2][i-1][j-1],dp[(tot-1)%2][i][j]})+a[i][tot-i];
                else
                {
                    dp[tot%2][i][j]=max(dp[tot%2][i][j],dp[(tot-1)%2][i-1][j]+a[i][tot-i]+a[j][tot-j]);
                    dp[tot%2][i][j]=max(dp[tot%2][i][j],dp[(tot-1)%2][i][j-1]+a[i][tot-i]+a[j][tot-j]);
                    dp[tot%2][i][j]=max(dp[tot%2][i][j],dp[(tot-1)%2][i-1][j-1]+a[i][tot-i]+a[j][tot-j]);
                    dp[tot%2][i][j]=max(dp[tot%2][i][j],dp[(tot-1)%2][i][j]+a[i][tot-i]+a[j][tot-j]);
                }
            }
        for(int i=1;i<=tot-1;i++)
            for(int j=1;j<=tot-1&&j<=i;j++)
                dp[(tot-1)%2][i][j]=-INF;
    }

    printf("%lld",dp[(2*n)%2][n][n]);
    return 0;
}

 

标签:CF213C,ch,int,max,tot,例题,dp,define
From: https://www.cnblogs.com/Willette/p/17382995.html

相关文章

  • UDP组播的c++实现
    1写socket的时候UDP和TCP的代码区别就是是否有连接过程;有connect连接的代码的就是TCP,没有连接的就是UDP以下代码是发送信息给组播地址(没有写接收代码。接收的代码就是要写个加入多播组,从多播组接收的逻辑)参考:https://blog.csdn.net/zhizhengguan/article/details/109312144/......
  • UDP内核发包流程
    背景工作中遇到客户反馈,上层应用UDP固定间隔100ms发包,但本地tcpdump抓包存在波动,有的数据包之间间隔107ms甚至更多,以此重新梳理了下udp的发送流程。udp发包流程udp_sendmsgUDPcorking是一项优化技术,允许内核将多次数据累积成单个数据报发送。在用户程序中有两种方法可以启......
  • (hdu step 3.2.1)Max Sum(简单dp:求最大子序列和、起点、终点)
    题目:MaxSumTimeLimit:2000/1000MS(Java/Others)MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):1390AcceptedSubmission(s):542 ProblemDescriptionGivenasequencea[1],a[2],a[3]......a[n],yourjobistocalculatethemaxsu......
  • (hdu step 3.2.3)Super Jumping! Jumping! Jumping!(DP:求最长上升子序列的最大和)
    题目:SuperJumping!Jumping!Jumping!TimeLimit:2000/1000MS(Java/Others)MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):896AcceptedSubmission(s):518 ProblemDescriptionNowadays,akindofchessgamecalled“SuperJumping!......
  • Python wordpress-xmlrpc错误:xml.parsers.expat.ExpatError: XML or text declaration
    解决方法:修改打开client.py文件原代码:deffeed(self,data):self._parser.Parse(data,0)改成如下的代码:deffeed(self,data):self._parser.Parse(data.strip(),0)......
  • Vulnhub-dpwwn01-WP
    前言点击>>下载靶机靶机kalilinux:ip地址为192.168.20.200靶机探测使用nmap探测靶机nmap192.168.20.0/24靶机ip为192.168.20.131使用nmap进行详细扫描nmap-A-p-192.168.20.131点击查看扫描结果rootin/home/kalivia☕v17.0.6…➜nmap-A-p-192.168.2......
  • [每天例题]蓝桥杯 C语言 谁拿了最多奖学金
    谁拿了最多奖学金题目   题目要求1.只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。2.每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写......
  • [每天例题]蓝桥杯 C语言 最小公倍数
    最小公倍数题目 思路分析方法一:建立两个for循环,第一个for循环求最小公倍数,第二个for循环进行1至n的排列方法二:/*最小公倍数n项可以计算前面的n-1项例如;1、2、3、4、5、6的最小公倍数=1、2、3、4、5的最小公倍数和6的最小公倍数我们定义一个贡献度:贡献度(ai)%贡献度(ai-1)==0......
  • 指数分布和泊松过程(Exponential Distribution and Poisson Process)--2(指数分布的例
    例1Supposethatcustomersareinlinetoreceiveservicethatisprovidedsequentiallybyaserver;wheneveraserviceiscompleted,thenextpersoninlineenterstheservicefacility.However,eachwaitingcustomerwillonlywaitanexponentiallydist......
  • UDP广播相关知识,chatGPT回答的
    1路由器和交换机哪个成环会引起广播风暴路由器和交换机都可能引起广播风暴,但是在成环的情况下,交换机更容易引起广播风暴。当交换机形成环路时,广播帧会在网络中不断循环,并且不断地复制并增加它们的数量,最终导致网络拥塞甚至崩溃。为了避免这种情况,网络管理员应该采取措施,例如使用S......