NOI2009 管道取珠 神仙DP
原题链接
原题让求的是\(\sum\limits a_i^2\),这个东西直接求非常难求。我们考虑转化一下问题。
首先把\(a_i^2\)拆成\((1+1+...+1)(1+1+...+1)\),两个括号中的\(1\)都有\(a_i\)个。为什么要这样呢?仔细理解一下拆开后的式子,是不是就是相当于分别操作两次,问最终序列相同的方案数?
这样的话\(DP\)就比较好想了,设\(f[i][j][k][l]\)表示第一次操作上管道已经取了\(i\)个,下管道取了\(j\)个,第二次操作上管道取了\(k\)个,下管道取了\(l\)个时相同的方案数。
显然,这样会炸空间。又发现\(i+j=k+l\),所以最后一维可以扔了。
转移方程就不详细叙说了,写在代码里吧。最后还要来一个滚动数组优化空间!
#include <bits/stdc++.h>
using namespace std;
#define N 500
#define MOD 1024523
int n, m, f[2][N+5][N+5];
char s1[N+5], s2[N+5];
int main() {
    #ifndef ONLINE_JUDGE
        freopen("testdata.in", "r", stdin);
        freopen("testdata.out", "w", stdout);
    #endif
    scanf("%d%d", &n, &m);
    scanf("%s%s", s1+1, s2+1);
    for(int i = 1, j = n; i < j; ++i, --j) swap(s1[i], s1[j]);
    for(int i = 1, j = m; i < j; ++i, --j) swap(s2[i], s2[j]);
    f[0][0][0] = 1;
    int flag = 0;
    for(int i = 0; i <= n; ++i, flag ^= 1) {
        memset(f[flag^1], 0, sizeof f[flag^1]);
        for(int j = 0; j <= m; ++j)
            for(int k = 0, l; k <= min(n, i+j); ++k) {
                l = i+j-k;
                if(l < 0 || l > m) continue;
                //分4种情况分别转移
                if(s1[i+1] == s1[k+1]) f[flag^1][j][k+1] = (f[flag^1][j][k+1]+f[flag][j][k])%MOD;
                if(s2[j+1] == s1[k+1]) f[flag][j+1][k+1] = (f[flag][j+1][k+1]+f[flag][j][k])%MOD;
                if(s1[i+1] == s2[l+1]) f[flag^1][j][k] = (f[flag^1][j][k]+f[flag][j][k])%MOD;
                if(s2[j+1] == s2[l+1]) f[flag][j+1][k] = (f[flag][j+1][k]+f[flag][j][k])%MOD;
            }
    }
    printf("%d\n", f[flag^1][m][n]);
    return 0;
}
												
											NOI2009 管道取珠 神仙DP的更多相关文章
- 【BZOJ 1566】 1566: [NOI2009]管道取珠 (DP)
		
1566: [NOI2009]管道取珠 Time Limit: 20 Sec Memory Limit: 650 MBSubmit: 1659 Solved: 971 Description In ...
 - BZOJ1566 [NOI2009]管道取珠  【dp】
		
题目 输入格式 第一行包含两个整数n, m,分别表示上下两个管道中球的数目. 第二行为一个AB字符串,长度为n,表示上管道中从左到右球的类型.其中A表示浅色球,B表示深色球. 第三行为一个AB字符串, ...
 - NOI2009管道取珠(dp)
		
题意:给定两列球,可以从任意一列球的末尾弹出一个球,最后会得到一个序列,设第i种序列可以被a[i]种操作产生,那么会产生a[i]^2的贡献,求贡献和. Solution: 首先我们观察a[i]^2的含 ...
 - [NOI2009]管道取珠(DP)
		
Luogu1758 DarkBZOJ1566 题解 因为他要让我们求出每种状态出现次数的平方和,这样模拟两人取球的时候,设第一个人取球的方案为A,第二个人取球的方案为B, 这样对于每一个A,都有C(n ...
 - bzoj 1566: [NOI2009]管道取珠【dp】
		
想不出来想不出来 仔细考虑平方的含义,我们可以把它想成两个人同时操作,最后得到相同序列的情况 然后就比较简单了,设f[t][i][j]为放了t个珠子,A的上方管道到了第i颗珠子,B的上方管道到了第j颗 ...
 - Bzoj  1566: [NOI2009]管道取珠(DP)
		
1566: [NOI2009]管道取珠 Time Limit: 20 Sec Memory Limit: 650 MB Submit: 1558 Solved: 890 [Submit][Status ...
 - BZOJ.1566.[NOI2009]管道取珠(DP 思路)
		
BZOJ 洛谷 考虑\(a_i^2\)有什么意义:两个人分别操作原序列,使得得到的输出序列都为\(i\)的方案数.\(\sum a_i^2\)就是两人得到的输出序列相同的方案数. \(f[i][j][ ...
 - 【题解】NOI2009管道取珠
		
又是艰难想题的一晚,又是做不出来的一题 (:д:) 好想哭啊…… 这题最关键的一点还是提供一种全新的想法.看到平方和这种东西,真的不好dp.然而我一直陷在化式子的泥潭中出不来.平方能够联想到什么?原本 ...
 - bzoj1566: [NOI2009]管道取珠 DP
		
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1566 思路 n个球,第i个球颜色为ai,对于颜色j,对答案的贡献为颜色为j的球的个数的平 ...
 
随机推荐
- nginx系列9:HTTP反向代理请求处理流程
			
HTTP反向代理请求处理流程 如下图:
 - 倒计时5S秒自动关闭弹窗
			
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
 - Django之CSRF跨站请求伪造(老掉牙的钓鱼网站模拟)
			
首先这是一个测试的代码 请先在setting页面进行下面操作 注释完成后,开始模拟钓鱼网站的跨站请求伪造操作: 前端代码: <!DOCTYPE html> <html lang=&q ...
 - Ubuntu18.04下安装配置MongoDB4.0.6
			
搭建MongoDB环境 安装MongoDB 1.下载安装包 MongoDB 提供了 linux 各发行版本 64 位的安装包,你可以在官网下载安装包. 下载地址:https://www.mongodb ...
 - 第四次上机,ASP组件的使用
			
<html> <body> <% '以下连接数据库,建立一个Connection对象实例conn Set conn=Server.CreateObject("A ...
 - Android为TV端助力 转载:RecyclerView分页加载
			
package com.android.ryane.pulltoloaddata_recyclerview; import android.os.Handler;import android.os.L ...
 - JMeter接口测试实战-动态数据验证
			
JMeter接口测试实战-动态数据验证 说到验证就不得不说断言, 先来看下JMeter官方给出断言(Assertion)的定义, 用于检查测试中得到的响应数据等是否符合预期,用以保证测试过程中的数据交 ...
 - SQL 修改字段类型和长度,常见类型介绍及数据库设计工具PowerDesigner和astah
			
1.电话字段设置24个Byte竟然不够,好吧设置为50的长度. alter table <表名> alter column <字段名> 新类型名(长度) 举例: ) 2.删除一 ...
 - iBatis第三章:iBatis的基本用法
			
iBatis 在DAO层的用法很基础,和一般 JDBC 用法没太多的不同之处,主要是实现数据的持久化.它的优势是用法比较灵活,可以根据业务需要,写出适应需要的sql,其使用简单,只要会使用sql,就能 ...
 - SQLServer之数据库行锁
			
行锁使用注意事项 1.ROWLOCK行级锁确保在用户取得被更新的行,到该行进行更新,这段时间内不被其它用户所修改.因而行级锁即可保证数据的一致性,又能提高数据操作的并发性. 2.ROWLOCK告诉SQ ...