提高历练地 动态规划TG.lv(1) 小a和uim之大逃离
2018-03-08 15:27
260 查看
题目链接:
https://www.luogu.org/problemnew/show/P1373
dp[i][j][k][l]dp[i][j][k][l] 表示在(i,j)(i,j)处,第ll个人走完后,差值为kk的情况。
然后我按照这种写法写了之后,发现应该是T掉了6个点,我感觉应该是因为Java太慢了,于是决定改成C++试一下。
然后显然,是因为Java太慢了,改成C++之后,直接过掉了。
改写之后的C++代码。
https://www.luogu.org/problemnew/show/P1373
题意理解
首先,由于是要找所有的解总数,因此显然是不能暴力检查每条路径的吧。。。然后再换一个思路,好像是可以考虑用深搜+递推记录数量。但是这样的话,好像是可以直接拿循环来写。然后再改改好像就成了dp?dp[i][j][k][l]dp[i][j][k][l] 表示在(i,j)(i,j)处,第ll个人走完后,差值为kk的情况。
然后我按照这种写法写了之后,发现应该是T掉了6个点,我感觉应该是因为Java太慢了,于是决定改成C++试一下。
然后显然,是因为Java太慢了,改成C++之后,直接过掉了。
我的代码
不能过掉全部样例的Java代码。import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { static int n, m, k; static int MOD = 1000000007; static int[][][][] dp; public static void main(String[] args) { FastScanner fs = new FastScanner(); n = fs.nextInt(); m = fs.nextInt(); k = fs.nextInt(); k++; dp = new int [m][k][2]; int[][] nums = new int [m]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { nums[i][j] = fs.nextInt(); dp[i][j][nums[i][j] % k][0] = 1; } } int res = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { for (int t = 0; t < k; t++) { if (i - 1 >= 0) { dp[i][j][t][1] = (dp[i - 1][j][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD; dp[i][j][t][0] = (dp[i - 1][j][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD; } if (j - 1 >= 0) { dp[i][j][t][1] = (dp[i][j - 1][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD; dp[i][j][t][0] = (dp[i][j - 1][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD; } } res = (res + dp[i][j][0][1]) % MOD; } } System.out.println(res); } public static class FastScanner { StringTokenizer st; BufferedReader br; private void eat(String s) { st = new StringTokenizer(s); } public FastScanner() { br = new BufferedReader(new InputStreamReader(System.in)); eat(""); } public String nextLine() { try { return br.readLine(); } catch (Exception e) { // TODO: handle exception } return null; } public boolean hasNext() { while (!st.hasMoreTokens()) { String s = nextLine(); if (s == null) { return false; } eat(s); } return true; } public String nextToken() { hasNext(); return st.nextToken(); } public int nextInt() { return Integer.valueOf(nextToken()); } } }
改写之后的C++代码。
#include<stdio.h> void read(int &x) { x = 0; int f = 1; char ch = getchar(); while(ch > '9'||ch < '0') { if(ch == '-') { f = -1; } ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + (int)(ch - 48); ch = getchar(); } x = x * f; } int n, m, k; const int MOD = 1000000007; const int maxn = 805; int dp[maxn][maxn][17][2]; int nums[maxn][maxn]; int main() { read(n); read(m); read(k); k++; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { read(nums[i][j]); dp[i][j][nums[i][j] % k][0] = 1; } } int res = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { for (int t = 0; t < k; t++) { if (i - 1 >= 0) { dp[i][j][t][1] = (dp[i - 1][j][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD; dp[i][j][t][0] = (dp[i - 1][j][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD; } if (j - 1 >= 0) { dp[i][j][t][1] = (dp[i][j - 1][(t + nums[i][j]) % k][0] + dp[i][j][t][1]) % MOD; dp[i][j][t][0] = (dp[i][j - 1][(t - nums[i][j] + k) % k][1] + dp[i][j][t][0]) % MOD; } } res = (res + dp[i][j][0][1]) % MOD; } } printf("%d", res); return 0; }
相关文章推荐
- 【Luogu1373】小a和uim之大逃离(动态规划)
- 【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]
- 蓝桥杯 算法提高 拿糖果(筛法+动态规划)
- 【jzoj5350】【NOIP2017提高A组模拟9.7】【陶陶摘苹果】【动态规划】
- 蓝桥杯_算法提高_金明的预算方案(动态规划、01背包变形)
- 洛谷1373 小a和uim之大逃离
- NOIP 2006 - 提高组 金明的预算 动态规划(DP)
- 【动态规划】【记忆化搜索】1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组
- 划分型动态规划 之 CODE[VS] 1017 乘积最大 2000年NOIP全国联赛提高组
- 划分型动态规划 之 CODE[VS] 1040 统计单词个数 2001年NOIP全国联赛提高组
- TG(提高篇)第15讲 实践项目 简单银行系统(函数篇)
- 洛谷 P1373 小a和uim之大逃离
- 【NOIP2010提高组】乌龟棋(动态规划)
- 【动态规划】Vijos P1313 金明的预算方案(NOIP2006提高组第二题)
- 【动态规划】Vijos P1493 传纸条(NOIP2008提高组第三题)
- 【jzoj5248】【NOIP2017提高A组模拟8.10】【花花的聚会】【动态规划】【可持久化线段树】
- 蓝桥杯 ADV-205算法提高 拿糖果(动态规划)
- 蓝桥杯 ADV-165算法提高 超级玛丽(动态规划、递推)
- 洛谷P1373 小a和uim之大逃离(DP)
- NOIP 2010 - 提高组 乌龟棋 动态规划 重庆一中高2018级竞赛班第八次测试 2016.8.7 Problem 2