zoukankan      html  css  js  c++  java
  • [CF41D] Pawn 题解

    题目链接

    题目大意

    在一个树阵中按一定走法取一些树,使和最大且被 k+1整除

    解题思路

    类似一个数塔问题

    因为最后的结果要被 k+1 整除,所以可以记录到每一个点  对 k+1 取余结果不同的最优解(最大值),不用记录每一个数,浪费空间和时间

    举个例子:

    当到达 (i, j) 这个点时,有两种路线得到的值分别为a, b(a>b),且a % (k+1) = x, b % (k+1) = x,那么此时只需记录a,将b舍去

    因为余数相同不会对后面的结果产生影响

    最后枚举最后一行对 k+1取余结果为0的结果,取最大值

    空间 n*m*k, 时间n*m*k

    路径记录

    再开两个数组分别记录每个最优解是由哪个状态转移而来的,输出时递归输出 递归过程

    void print (int x, int y, int q) {    // 递归到第x行,第y列,%(k+1) 的结果为q 
    	if (x == n) printf ("%d
    ", y);
    	else {
    		print (x + 1, y + ans[x][y][q].lr, ans[x][y][q].mod);
    		if (ans[x][y][q].lr == 1) putchar ('L');
    		else putchar ('R');
    	}
    }

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct e {int lr, mod;} ans[105][105][15]; //ans记录每一步方向及 %k的余数
    int n, m, k, a[105][105], f[105][105][15], w; 
    char ch;
    void print (int x, int y, int q) {    // 递归到第x行,第y列,%(k+1) 的结果为q 
    	if (x == n) printf ("%d
    ", y);
    	else {
    		print (x + 1, y + ans[x][y][q].lr, ans[x][y][q].mod);
    		if (ans[x][y][q].lr == 1) putchar ('L');
    		else putchar ('R');
    	}
    }
    int main(){
        scanf ("%d %d %d", &n, &m, &k); k++;
        for (int i = 1; i <= n; i++)
          for (int j = 1; j <= m; j++)  cin >> ch, a[i][j] = ch -'0';
        memset (f, -1, sizeof (f));
        for (int i = 1; i <= m; i++)  f[n][i][a[n][i]%k] = a[n][i];
        for (int i = n - 1; i; i--)
          for (int j = 1; j <= m; j++)
            for (int p = 0; p < k; p++) {
              int t = (p + a[i][j]) % k;
              if (j != 1 and f[i+1][j-1][p] >= 0) 
                f[i][j][t] = f[i+1][j-1][p] + a[i][j], ans[i][j][t] = (e) {-1, p};
              if (j != m and f[i+1][j+1][p] >= 0 and f[i+1][j+1][p] + a[i][j] > f[i][j][t]) 
                f[i][j][t] = f[i+1][j+1][p] + a[i][j], ans[i][j][t] = (e) {1, p};
            }
        for (int i = 1; i <= m; i++) if (f[1][i][0] > f[1][w][0]) w = i;  //找到起始位置 
        if (!w) {puts("-1"); return 0;}
        printf ("%d
    ", f[1][w][0]);
        print (1, w, 0);
        return 0;
    }
    

      

  • 相关阅读:
    Python利用Remove.bg接口自动消除图片背景
    解决ajxa跨域问题
    CentOS7 修改静态IP
    CentOS下 安装composer 与tp5.1
    centon 安装php-fpm+Nginx
    win10 安装selenium和使用
    Scrapy 爬虫框架入门
    Python 异常处理
    selenium和phantomjs的介绍
    MongoDB入门
  • 原文地址:https://www.cnblogs.com/whx666/p/10633305.html
Copyright © 2011-2022 走看看