CodeForces 132C Logo Turtle 四维DP 递推

                  好吧,这道题目居然是动态规划。。涨姿势了。。。原来也可以这样设置状态。。

                  需要开一个bool数组来表示这个状态是不是可以到达,最后在所有状态里面遍历一遍,取最大的。

                  arr[i][j][k][l]表示执行到i条指令离坐标j变换了k条指令方向为l的状态可不可达(l表示方向,0表示和原点相同,1表示相反)

                  因为从原点可以往两边走,所以把原点设在坐标为100的地方了,所以一开始是arr[0][0][100][0]=true。

                 状态转移方程: if str[i] is 'T' 

                                                               if arr[i][j][k][l^1] is true -> arr[i][j][k][l] := true

                                                               if k>0&&arr[i-1][j+(l==0?-1:1)][k-1][l] -> arr[i][j][k][l] := true //此处在考虑把T变换成F,同时需要考虑到方向的问题

                 str[i]是F的情况在此不予列出,自己动手推一下很快的。

                 最后就是题目要求的变换n次时候的最大值,但是仔细想一下,这个变换变两次之后又回来了,因此可以通过这个来故意浪费变换次数,要注意的应该就这些了

                 挺不错的一道题目。

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

char str[110];
int n,ans,len;
bool arr[110][220][55][2];

int main(){
    scanf("%s%d",str+1,&n);
    len=strlen(str+1);
    arr[0][100][0][0]=true;
    for(int i=1;str[i];++i)
    for(int j=100-i;j<=100+i;++j)
    for(int k=0;k<=i&&k<=n;++k)
    for(int l=0;l<=1;++l){
        if(str[i]=='T'){
            if(arr[i-1][j][k][l^1])
                arr[i][j][k][l]=true;
            if(k>0&&(arr[i-1][j+((l==0)?-1:1)][k-1][l]))
                arr[i][j][k][l]=true;
        }
        else{
            if(arr[i-1][j+((l==0)?-1:1)][k][l])
                arr[i][j][k][l]=true;
            if(k>0&&arr[i-1][j][k-1][l^1])
                arr[i][j][k][l]=true;
        }
    }

    for(int j=100-len;j<=100+len;++j)
    for(int k=n;k>=0;k-=2)
    for(int l=0;l<=1;++l)
    if(arr[len][j][k][l])
    ans=max(ans,abs(100-j));

    printf("%d\n",ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
引用\[1\]中提到了一种树形动态规划的方法来解决CodeForces - 982C问题。在这个问题中,subtree指的是子连通块,而不是子树。为了使cnt_white - cnt_black尽可能大,可以使用两次树形动态规划来求解。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。如果ans\[u\]为正,则减去dp\[v\]就是树链所代表的子树的权值。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] 问题: CodeForces - 982C 树形DP是什么问题?如何解决? 回答: CodeForces - 982C是一个树形动态规划问题。在这个问题中,需要求解子连通块的最大权值和,使得cnt_white - cnt_black尽可能大。解决这个问题的方法是使用两次树形动态规划。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] #### 引用[.reference_title] - *1* *2* [CodeForces - 1324F Maximum White Subtree(树形dp)](https://blog.csdn.net/qq_45458915/article/details/104831678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值