https://www.cnblogs.com/31415926535x/p/10423047.html

这道题是大连的某一年的现场赛的题hdu-4055

,,,刚开始做线性dp的题,,看了好半天才看懂解法,,

分析

参考1

参考2

题目的意思就是给出一个仅有1~n组成的序列的关系s:'I'表示 \(a[i+1]>a[i]\),'D'表示 \(a[i+1] < a[i]\),,'?'表示都可以,,然后问你所有可能的情况的总数,,

用 \(dp[i][j]\) 表示长度为i并且仅由1~i组成的序列以j结尾时的种类数,,

  • 当 \(s[i]= ?\) 时,,当前点的可能情况就是前面所有情况的和,即 \(dp[i][j]=\sum_{k=1}^{i-1}dp[i-1][k]\)

  • 当 \(s[i]=I\) 时,,因为第i位固定就为j了,并且前一位要满足小于等于j,所以就要找出所有长度为i-1且结尾小于等于j-1的情况的和,,即: \(dp[i][j]=\sum_{k=1}^{j-1}dp[i-1][k]\)

  • 当 \(s[i]=D\) 时,,和等于I的情况相反,,也就是要找到所有长度为i-1且最后一位大于j的种类数(同时要小于i-1),,也就是说可以直接用?的种类数减去I的种类数,,即: \(dp[i][j]=\sum_{k=j}^{i-1}dp[i-1][k]=\sum_{k=1}^{i-1}dp[i-1][k]-\sum_{k=1}^{j-1}dp[i][k]\)

假定每次使第i位为j时,前面大于等于j的值都加一,,这样保证前i个数都出现一次,,同时i-1变成了i,,j变成了j+1,,j就放在了后面,,所以遍历中的k是从j~i-1,,,

参考

最后用前缀和维护一下那个和,空间换时间

代码

//hdu
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <algorithm>
#include <queue>
#define aaa cout<<233<<endl;
#define endl '\n'
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;//1061109567
const ll linf = 0x3f3f3f3f3f3f3f;
const double eps = 1e-6;
const double pi = 3.14159265358979;
const int maxn = 1e3 + 5;
const int maxm = 2e5 + 5;
const ll mod = 1e9 + 7;
int dp[maxn][maxn], sum[maxn][maxn];
char s[maxn];
int main()
{
// freopen("233.in" , "r" , stdin);
// freopen("233.out" , "w" , stdout);
// ios_base::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
while(~scanf("%s", s + 2))
{
int len = strlen(s + 2);
memset(dp, 0, sizeof dp);
memset(sum, 0, sizeof sum);
dp[1][1] = sum[1][1] = 1;
for(int i = 2; i <= len + 1; ++i)
{
for(int j = 1; j <= i; ++j)
{
if(s[i] == 'I')
dp[i][j] = sum[i - 1][j - 1];
if(s[i] == 'D')
dp[i][j] = (sum[i - 1][i - 1] - sum[i - 1][j - 1] + mod) % mod;
if(s[i] == '?')
dp[i][j] = sum[i - 1][i - 1];
sum[i][j] = (dp[i][j] + sum[i][j - 1]) % mod;
}
}
printf("%d\n", sum[len + 1][len + 1]);
}
return 0;
}

(end)

最新文章

  1. 解析大型.NET ERP系统 高质量.NET代码设计模式
  2. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
  3. 运行第一个PHP程序
  4. Node聊天程序实例06:server.js
  5. vc6.0如何显示行号以及出现版本不兼容问题
  6. hadoop常见问题汇集
  7. docker中使用systemd
  8. C#_delegate - 值参数和引用参数
  9. Ajax在PC端可以使用但在手机端不能使用
  10. Java数据结构与算法(2) - ch03排序(冒泡、插入和选择排序)
  11. Android Data Binding使用笔记
  12. Docker 概览
  13. 如何处理Express异常?
  14. python UDP套接字通信
  15. LDAP学习笔记总结
  16. 用vue的自定义组件写了一个拖拽 组件,局部的 只能在自定义元素内的
  17. oracle /*+ SYS_DL_CURSOR */ 这个hint
  18. Go Example--for循环
  19. Netty实践二(心跳检测)
  20. mongo远程登录

热门文章

  1. SpringBoot使用Redis缓存
  2. 【vim】删除标记内部的文字 di[标记]
  3. jq常用功能操作
  4. crontab在/var/log/目录下没有cron.log文件
  5. C++中template的简单用法
  6. js实现弹窗居中
  7. zabbix系列(四)Zabbix3.0.4添加对Nginx服务的监控
  8. cacti系列(三)之cacti添加对mysql服务器主从的监控
  9. android 获取手机GSM/CDMA信号信息,并获得基站信息
  10. PYTHON-模块 json pickle shelve xml