额。果然是动(dou)态(bu)规(hui)划(zuo)专场。。。

A: 翻倍序列

dp[i][j]表示第i个位置是j的情况的个数
那么dp[i][j]=∑dp[i-1][k]   (j%k==0)
初始状态下dp[0][j]=1。(1<=j<=n)
最后要求的答案是∑dp[n-1][i]  (1<=i<=n)

可以先预处理好所有答案,然后询问的时候直接求和输出。

 #include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#define FOR(i,n) for(i=0;i<(n);i++)
#define CLR(a) memset(a,0,sizeof(a))
#define CIN(a) scanf("%d",&a)
typedef long long ll;
using namespace std;
int dp[][];
const int MOD=;
int main()
{
int n,k,i,j,kk;
n=,k=;
for(j=;j<=n;j++) dp[][j]=;
for(i=;i<k-;i++){
for(j=;j<=n;j++){
for(kk=j;kk<=n;kk+=j){
dp[i+][kk]=(dp[i+][kk]+dp[i][j])%MOD;
}
}
}
while(scanf("%d%d",&n,&k)!=EOF) {
int ans=;
for(j=;j<=n;j++){
ans=(ans+dp[k-][j])%MOD;
}
printf("%d\n",ans);
}
return ;
}

B: 汉诺塔

dp[k][i][j]表示把k个盘子从i移动到j所需要的最小花费。

首先z=3-i-j,表示除了i和j的另一个柱子

那么移动的时候有2种情况:
1.先把k-1个从i移动到z,然后把最大的那个从i移动到j,最后把z-1个从k移动到j
  也就是dp[k][i][j]=dp[k-1][i][z]+cost[i][j]+dp[k-1][z][j]

2.先把k-1个从i移动到j,然后把最大的那个从i移动到z,之后把k-1个从j移动回i,再把最大的从z移动到j,最后k-1个从i移动到j
  也就是dp[k][i][j]=dp[k-1][i][j]+cost[i][z]+dp[k-1][j][i]+cost[z][j]+dp[k-1][i][j]

然后两者取较小值。
最后要注意的是dp[0][i][j]=min{cost[i][j] ,   cost[i][z]+cost[z][j]}

 #include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#define FOR(i,n) for(i=0;i<(n);i++)
#define CLR(a) memset(a,0,sizeof(a))
#define CIN(a) scanf("%d",&a)
typedef long long ll;
using namespace std;
int cost[][];
ll DP[][][];
ll dfs(int n,int i,int j){
//printf("%d %d %d\n",n,i,j);
int k=-i-j;
if(n==) return min(cost[i][j],cost[i][k]+cost[k][j]);
if(DP[n][i][j]!=-){
return DP[n][i][j];
}
ll ans1=;
ans1=dfs(n-,i,k);
ans1+=cost[i][j];
ans1+=dfs(n-,k,j); ll ans2=;
ans2=dfs(n-,i,j);
ans2+=cost[i][k];
ans2+=dfs(n-,j,i);
ans2+=cost[k][j];
ans2+=dfs(n-,i,j); return DP[n][i][j]=min(ans1,ans2);
}
int main()
{
int n;
while(scanf("%d%d%d",&cost[][],&cost[][],&cost[][])!=EOF)
{
memset(DP,-,sizeof(DP));
scanf("%d%d%d",&cost[][],&cost[][],&cost[][]);
scanf("%d%d%d",&cost[][],&cost[][],&cost[][]);
scanf("%d",&n);
printf("%lld\n",dfs(n,,));
}
return ;
}

C: 红黑树

dp[i][0]表示有i个节点的树,如果根节点是黑色,有几种构造。
dp[i][1]表示有i个节点的树,如果根节点是红色,有几种构造。

根据题意可知,最后要求的就是dp[n][0]的值(根节点必须是是黑色)
dp[i][0]= dp[i/2+i%2][0]*dp[i/2][0]
     +dp[i/2+i%2][0]*dp[i/2][1]
     +dp[i/2+i%2][1]*dp[i/2][0]
     +dp[i/2+i%2][1]*dp[i/2][1]
dp[i][1]= dp[i/2+i%2][0]*dp[i/2][0]

dp[1][0]=1
dp[1][1]=0  (叶子节点不能是红色)

dp[2][1]=dp[2][0]=1

然后递推就行了。。

 #include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#define FOR(i,n) for(i=0;i<(n);i++)
#define CLR(a) memset(a,0,sizeof(a))
#define CIN(a) scanf("%d",&a)
typedef long long ll;
using namespace std;
const ll MOD=;
ll DP[][];
ll dfs(int x,int c)//x个节点,根节点颜色是c(0黑 1红)
{
//if(x<0) return 0;
if(x==&&c==) return ;//叶子节点不能是红色
if(x==) return ;//叶子节点是黑色
if(DP[x][c]!=) return DP[x][c];
ll ret=,l,r;
if((x-)%) l=(x-)/+;
else l=(x-)/;
r=(x-)/;
if(!c){//黑色
if(r!=){
ret=(ret+(dfs(l,)*dfs(r,))%MOD)%MOD;
ret=(ret+(dfs(l,)*dfs(r,))%MOD)%MOD;
ret=(ret+(dfs(l,)*dfs(r,))%MOD)%MOD;
ret=(ret+dfs(l,)*dfs(r,)%MOD)%MOD;
}else{ret=;}
}else{
if(r!=){
ret=(ret+dfs(l,)*dfs(r,)%MOD)%MOD;
}else{ret=;}
}
return DP[x][c]=ret;
}
int main()
{
int n;
memset(DP,,sizeof(DP));
while(scanf("%d",&n)!=EOF){
printf("%lld\n",dfs(n,));
}
return ;
}

D: 01序列

dp[i][0]表示前i个字符组成的的子序列中 以0为结尾的01序列
dp[i][1]表示前i个字符组成的的子序列中 以1为结尾的01序列
dp[i][0]=dp[i-1][1]+1      dp[i][1]=dp[i-1][1]  (s[i]==0)
dp[i][1]=dp[i-1][0]+1      dp[i][0]=dp[i-1][0]  (s[i]==1)

把全部加起来就是答案了。

 #include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#define FOR(i,n) for(i=0;i<(n);i++)
#define CLR(a) memset(a,0,sizeof(a))
#define CIN(a) scanf("%d",&a)
typedef long long ll;
using namespace std;
int main()
{
int n,i;
int MOD=;
while(scanf("%d",&n)!=EOF){
ll ans=;
ll a0=,a1=;
for(i=;i<n;i++){
if(i%){
ans=(ans+(a0+))%MOD;
a1=(a1+a0+)%MOD;
}else{
ans=(ans+(a1+))%MOD;
a0=(a0+a1+)%MOD;
}
}
printf("%lld\n",ans);
}
return ;
}

E: 矩阵的最长不降子串

dp[i][j]表示以a[i][j]结尾的不递减子串最长的长度

那么dp[i][j]=max{
            if(a[i][j]>=a[i-1][j])   dp[i-1][j]+1
            if(a[i][j]>=a[i][j-1])   dp[i][j-1]+1
}
最后答案是最大的dp[i][j]

 #include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#define FOR(i,n) for(i=0;i<(n);i++)
#define CLR(a) memset(a,0,sizeof(a))
#define CIN(a) scanf("%d",&a)
typedef long long ll;
using namespace std;
int dp[][];
int a[][];
int n,m;
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)!=EOF){
int ans=;
for(i=;i<n;i++){
for(j=;j<m;j++){
scanf("%d",&a[i][j]);
dp[i][j]=;
if(i!=&&a[i-][j]<=a[i][j]){
dp[i][j]=max(dp[i][j],dp[i-][j]+);
}
if(j!=&&a[i][j-]<=a[i][j]){
dp[i][j]=max(dp[i][j],dp[i][j-]+);
}
ans=max(ans,dp[i][j]);
}
}
printf("%d\n",ans);
}
return ;
}

【解题报告】13级个人结业赛(二) ——动(dou)态(bu)规(hui)划(zuo)专场的更多相关文章

  1. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

  2. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  3. 2014 ACM/ICPC 鞍山赛区现场赛 D&amp;I 解题报告

    鞍山现场赛结束了呢-- 我们出的是D+E+I三道题-- 吾辈AC掉的是D和I两道,趁着还记得.先在这里写一写我写的两道水题D&I的解题报告吧^_^. D题的意思呢是说星云内有一堆排成一条直线的 ...

  4. 10.30 NFLS-NOIP模拟赛 解题报告

    总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...

  5. nowcoder(牛客网)OI测试赛2 解题报告

    qwq听说是一场普及组难度的比赛,所以我就兴高采烈地过来了qwq 然后发现题目确实不难qwq.....但是因为蒟蒻我太蒻了,考的还是很差啦qwq orz那些AK的dalao们qwq 赛后闲来无事,弄一 ...

  6. 冲刺Noip2017模拟赛3 解题报告——五十岚芒果酱

    题1  素数 [问题描述] 给定一个正整数N,询问1到N中有多少个素数. [输入格式]primenum.in 一个正整数N. [输出格式]primenum.out 一个数Ans,表示1到N中有多少个素 ...

  7. ZROIDay4-比赛解题报告

    ZROIDay4-比赛解题报告 扯闲话 感觉这个出题人的题做起来全都没感觉啊,今天又凉了,T1完全不知道什么意思,T2只会暴力,T3现在还不懂什么意思,真的太菜了 A 题意半天没搞懂爆零GG了,讲了一 ...

  8. ZROIDay3-比赛解题报告

    ZROIDay3-比赛解题报告 瞎扯 从今天开始考试有点不在状态,可能是因为不太适应题目的原因,T1已经接近了思想但是没有想到状态转移,T2思考方向错误,T3不会打LCT,还是太菜了 A 考场上想到要 ...

  9. 模拟赛T2 交换 解题报告

    模拟赛T2 交换 解题报告 题目大意: 给定一个序列和若干个区间,每次从区间中选择两个数修改使字典序最小. \(n,m\) 同阶 \(10^6\) 2.1 算法 1 按照题意模拟,枚举交换位置并比较. ...

随机推荐

  1. Educational Codeforces Round 54 (Rated for Div. 2) DE

    D 给出一个无向图,需要删去一些边,想知道最后能有多少个点到1的距离还是过去那么短 如果求一个最短路,然后从删边的角度看,看起来很难做,但是如果从零开始加边就会有做法,如同prim那样,先加入和1直接 ...

  2. eclipse创建文件package,source folder和folder区别及相互转换

    原文:http://blog.csdn.net/u014079773/article/details/66973910 https://www.cnblogs.com/shihaiming/p/735 ...

  3. Python类变量,实例变量,类方法,实例方法,静态方法的分析

    Python作为动态语言,跟静态语言如c/c++有很大区别,其中的一个重要的特性就是Python的变量无需声明直接可用.同样,类的成员变量无需声明,直接可用.目的是为了动态语言跟灵活,在思路想到的时候 ...

  4. webstorm的安装、激活码、更换主题颜色的修改、汉化

    一.安装 1.解压webstorm11zh.rar,双击.exe文件,下一步安装,在安装结束前会提示输入激活码,这个从网上随便找一个可用的即可. 二.更换主题颜色: 1.先从网上找一个喜欢的主题颜色, ...

  5. PWA web应用模型

    2018年的第一篇博客,最近都去挤图书馆了,希望新年新气象... 简介 PWA 是一门Google推出的web前端新技术,全称是Progressive Web App,是Google在2015年提出, ...

  6. 15 个有趣的 JS 和 CSS 库

    开发者们,一起来看看有木有你需要的前端库. 1. DisplayJS DisplayJS 是一个帮助你渲染 DOM 的简易框架.使用它,你可以更容易地将 JS 变量遍历到特定的 HTML 元素中,类似 ...

  7. linux下查看进程路径

    在linux下查看进程大家都会想到用 ps -ef|grep XXX可是看到的不是全路径,怎么看全路径呢?每个进程启动之后在 /proc下面有一个于pid对应的路径例如:ps -ef|grep pyt ...

  8. idea maven install时,打包找不到微服务common中公用的包

    如题:其实很简单,在打包之前要先使项目通过编译,编译通过之后再打包就可以了. 附idea编译键:

  9. hdu1569

    题解: 网络流 最大权独立集=总和-最大流 然后构图 代码: #include<cstdio> #include<cmath> #include<cstring> ...

  10. The main points of capacitive screen technology