A HDU_2048 数塔

dp入门题——数塔问题;求路径的最大和;

状态方程:

dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+a[i][j];
dp[n][j] = a[n][j];

其中dp[i][j]: 深度为i的第j个结点的最大和;

 /*
Problem: HDU-2048
Tips: Easy DP
dp[i][j]: 深度为i的第j个结点的最大和;
dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+a[i][j];
dp[n][j] = a[n][j];
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = ;
int a[maxn][maxn], dp[maxn][maxn];
int n;
void DP()
{
memset(dp, , sizeof(dp));
for(int j = ; j <= n; j++) dp[n][j] = a[n][j];
for(int i = n-; i >= ; i--)
{
for(int j = ; j <= i; j++)
{
dp[i][j]=max(dp[i+][j], dp[i+][j+])+a[i][j];
}
}
printf("%d\n", dp[][]);
}
int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = ; i <= n; i++)
for(int j = ; j <= i; j++)
scanf("%d", &a[i][j]);
DP();
} return ;
}

B HDU_1176 免费馅饼

数塔问题变形

状态方程:

dp[i][j] = max(dp[i+1][j-1], dp[i+1][j], dp[i+1][j+1])+a[i][j]; (注意要从后往前推)

dp[i][10] = max(dp[i+1][j-1], dp[i+1][j])+a[i][10];

dp[i][0] = max(dp[i+1][j], dp[i+1][j+1])+a[i][0];

其中dp[i][j]:第i时刻在位置j的接到的最多馅饼数;

 /*
Problem: HDU-2048
Tips: Easy DP
dp[i][j]: 深度为i的第j个结点的最大和;
dp[i][j] = max(dp[i+1][j-1], dp[i+1][j], dp[i+1][j+1])+a[i][j];
dp[i][10] = max(dp[i+1][j-1], dp[i+1][j])+a[i][10];
dp[i][0] = max(dp[i+1][j], dp[i+1][j+1])+a[i][0];
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = ;
int dp[maxn][], a[maxn][];
int main()
{
int n;
while(scanf("%d", &n) && n)
{
memset(a, , sizeof(a));
int maxt = ;
int t, p;
for(int i = ; i < n; i++)
{
scanf("%d%d", &p, &t);
a[t][p]++;
maxt = max(maxt, t);
}
memset(dp, , sizeof(dp));
for(int j = ; j <= ; j++) dp[maxt][j] = a[maxt][j];
for(int i = maxt-; i >= ; i--)
{
for(int j = ; j <= ; j++)
{
dp[i][j] = max(dp[i+][j], max(dp[i+][j+], dp[i+][j-]))+a[i][j];
}
dp[i][] = max(dp[i+][], dp[i+][])+a[i][];
dp[i][] = max(dp[i+][], dp[i+][])+a[i][];
} printf("%d\n", dp[][]);
}
return ;
}

C HDU_1087 Super Jumping! Jumping! Jumping!

状态方程:

dp[j] = v[i]<v[j] ? dp[i]+v[j] : dp[j];
dp[0] = 0;
其中dp[j]: 到第j步时,棋子的最大和

感觉自己推的方程毫无技术含量

 /*
Problem: HDU-2048
Tips: Easy DP
dp[j]: 到第j步时,棋子的最大和
dp[j] = v[i]<v[j] ? dp[i]+v[j] : dp[j];
dp[0] = 0;
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = ;
int dp[maxn], v[maxn];
int main()
{
int n;
while(~scanf("%d", &n) && n)
{
memset(dp, , sizeof(dp));
int _max = ;
for(int i = ; i <= n; i++) {scanf("%d", &v[i]); dp[i] = v[i]; _max = max(_max, v[i]);}
dp[n+] = v[n+] = _max+; dp[] = v[] = ;
for(int i = ; i <= n; i++)
{
for(int j = i+; j <= n+; j++)
{
if(v[j] > v[i])
{
dp[j] = max(dp[j], dp[i]+v[j]);
}
}
}
printf("%d\n", dp[n+]-_max-);
}
return ;
}

E HDU_1058 Humble Numbers

求丑数。两种方法,之前一直用优先队列,dp的算法时间更短,这算法谁想出来的...

每个丑数都可以分解为2^a*3^b*5^c*7的乘积,每次找到最小的数分别乘以2,3,5,7然后放入队列中去。两种方法的基本原理都是这样。

dp:

 /*
Problem: HDU 1058
Times: 62MS
Tips: Easy DP
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = ;
const int pri[] = {, , , };
LL dp[maxn];
LL Min(LL a, LL b, LL c, LL d)
{
return min(a, min(b, min(c, d)));
} void init()
{
int p1, p2, p3, p4;
p1 = p2 = p3 = p4 = ;
dp[] = ;
int a, b, c, d;
for(int i = ; i <= ; i++)
{
a = dp[p1]*;
b = dp[p2]*;
c = dp[p3]*;
d = dp[p4]*;
dp[i] = Min(a, b, c, d);
if(dp[i] == a) p1++;
if(dp[i] == b) p2++;
if(dp[i] == c) p3++;
if(dp[i] == d) p4++;
}
} int main()
{
init();
int n;
while(~scanf("%d", &n) && n)
{
if(n% == && n% != )
{
printf("The %dst humble number is %I64d.\n", n, dp[n]);
}
else if(n% == && n% != )
{
printf("The %dnd humble number is %I64d.\n", n, dp[n]);
}
else if(n% == && n% != )
{
printf("The %drd humble number is %I64d.\n", n, dp[n]);
}
else
printf("The %dth humble number is %I64d.\n", n, dp[n]);
} return ;
}

优先队列:

 /*
Problem: HDU 1058
Times: 109MS
Tips: Easy DP
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<set>
#include<stack>
#include<algorithm>
#define LL long long
using namespace std;
//typedef long long LL;
const int pri[] = {, , , };
LL ans[]; void init()
{
priority_queue<LL, vector<LL>, greater<LL> > pq;
set<LL> s;
pq.push(); s.insert();
for(int i = ; ; i++)
{
LL x = pq.top(); pq.pop();
ans[i] = x;
if(i == ) return ;
for(int j = ; j < ; j++)
{
LL t = pri[j]*x;
if(!s.count(t))
{
s.insert(t);
pq.push(t);
}
}
}
} int main()
{
init();
int n;
while(~scanf("%d", &n) && n)
{
if(n% == && n% != )
{
printf("The %dst humble number is %I64d.\n", n, ans[n]);
}
else if(n% == && n% != )
{
printf("The %dnd humble number is %I64d.\n", n, ans[n]);
}
else if(n% == && n% != )
{
printf("The %drd humble number is %I64d.\n", n, ans[n]);
}
else
printf("The %dth humble number is %I64d.\n", n, ans[n]); }
return ;
}

G HDU_1159 Common Subsequence

LIC入门题+滚动数组

状态方程:

dp[i][j] = (s[i]==s2[j]) ? dp[i-1][j-1]+1 : max(dp[i-1][j], dp[i][j-1]);

其中dp[i][j] :s1串到i处,s2串到j处时最长上升子串的长度;

由状态方程可以看出,只需要知道i-1时的状态就可以推出i时的状态,因此可以只用一个2*maxn的数组存储状态值,那么看方程也可以根据j-1的状态推出j时的状态啊为什么不用2*2的?虽然方程表面上看来是这样,但是别忘了j是随着i的递增而循环的,每次i改变,状态量都会更新;

 /*
Problem: HDU 1159
Tips: LCS
*/ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<set>
#include<stack>
#include<algorithm>
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = ;
char s1[maxn], s2[maxn];
int dp[][maxn];
void LCS()
{
int l1 = strlen(s1+), l2 = strlen(s2+);
memset(dp, , sizeof(dp));
for(int i = ; i <= l1; i++)
{
for(int j = ; j <= l2; j++)
{
if(s1[i] == s2[j])
dp[i%][j] = dp[(i-)%][(j-)]+;
else
dp[i%][j] = max(dp[(i-)%][j], dp[i%][(j-)]);
}
}
printf("%d\n", dp[l1%][l2]);
} int main()
{
while(~scanf("%s%s", s1+, s2+))
{
LCS();
}
return ;
}

H HDU_1003 Max Sum

最大连续子串和入门题;blog有原题题解,不再赘述。

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<set>
#include<stack>
#include<algorithm>
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = ;
int n;
int a[maxn];
int dp[maxn]; void DP()
{
memset(dp, , sizeof(dp));
int _max = -INF;
int s, e; s = e = ;
for(int i = ; i <= n; i++)
{
dp[i] = dp[i-]> ? dp[i-]+a[i] : a[i];
if(dp[i] > _max)
{
_max = dp[i]; e = i;
}
}
printf("%d ", _max);
s = e;
for(int i = e; i >= ; i--)
{
if(dp[i]<) break;
s = i;
}
printf("%d %d\n", s, e);
} int main()
{
int T; scanf("%d", &T);
for(int kase = ; kase < T; kase++)
{
if(kase) printf("\n");
printf("Case %d:\n", kase+);
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d", &a[i]);
DP();
}
return ;
}

I HDU_4540 威威猫系列故事——打地鼠

状态方程:

dp[i][j] = min(dp[i-1][pos_last]+abs(pos_last-pos_now));

dp[0][j] = dp[1][j] = 0;

其中dp[i][j]: 第i时刻打位于j位置的地鼠消耗能量的最小值。

 /**/

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<algorithm>
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = ;
const int maxp = ;
int n, k;
int a[maxn][maxn];
int dp[maxn][maxp];
void DP()
{
memset(dp, INF, sizeof(dp));
for(int p = ; p < maxp; p++) dp[][p] = ;
for(int t = ; t <= n; t++)
for(int j = ; j < k; j++)
{
int pos_now = a[t][j];
int _min = INF;
for(int p = ; p < k; p++)
{
int pos_last = a[t-][p];
_min = min(_min, dp[t-][pos_last]+abs(pos_last-pos_now));
}
dp[t][pos_now] = _min;
}
int _min = dp[n][];
for(int p = ; p < k; p++)
_min = min(_min, dp[n][a[n][p]]);
printf("%d\n", _min);
} int main()
{
while(~scanf("%d%d", &n, &k))
{
for(int t = ; t <= n; t++)
for(int p = ; p < k; p++)
scanf("%d", &a[t][p]);
DP();
}
return ;
}

【dp入门题】【跟着14练dp吧...囧】的更多相关文章

  1. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  2. POJ 2342 树形DP入门题

    有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...

  3. (树形DP入门题)Anniversary party(没有上司的舞会) HDU - 1520

    题意: 有个公司要举行一场晚会.为了让到会的每个人不受他的直接上司约束而能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会再邀请他的直接的上司,但该人的上司的上司,上司的上司的上司等都可以邀请. ...

  4. UVA 674 Coin Change 换硬币 经典dp入门题

    题意:有1,5,10,25,50五种硬币,给出一个数字,问又几种凑钱的方式能凑出这个数. 经典的dp题...可以递推也可以记忆化搜索... 我个人比较喜欢记忆化搜索,递推不是很熟练. 记忆化搜索:很白 ...

  5. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  6. HDU 2089 不要62【数位DP入门题】

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  7. poj 2955 区间dp入门题

    第一道自己做出来的区间dp题,兴奋ing,虽然说这题并不难. 从后向前考虑: 状态转移方程:dp[i][j]=dp[i+1][j](i<=j<len); dp[i][j]=Max(dp[i ...

  8. 数位DP入门题——[hdu2089]不要62

    数位DP是我的噩梦. 现在初三了,却没AC过数位DP的题目. 感觉数位DP都是毒瘤-- 题目 hdu不用登录也可以进去,所以就不把题目copy到这里来了. 题目大意 求区间[n,m][n,m][n,m ...

  9. 洛谷 P1879 玉米田(状压DP入门题)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int M,N; int plant[maxn][maxn];/ ...

随机推荐

  1. Web Service学习之八:Soap消息详解

    一.区别概念 WSDL是网络服务描述语言,是XML文档:它包含一系列描述某个web service的定义或者说是规则.尤其是定义了传输Sope消息的结构 Soap:简单对象访问协议,是交换数据的一种协 ...

  2. HDU 5723 Abandoned country (最小生成树 + dfs)

    Abandoned country 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5723 Description An abandoned coun ...

  3. HDU 5660 jrMz and angles (暴力枚举)

    jrMz and angles 题目链接: http://acm.hust.edu.cn/vjudge/contest/123316#problem/E Description jrMz has tw ...

  4. CodeForces 689A Mike and Cellphone (模拟+水题)

    Mike and Cellphone 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/E Description While sw ...

  5. Spring入门(2)-通过构造器注入Bean

    Spring入门(2)-通过构造器注入Bean 前一篇文章将了最基本的spring例子,这篇文章中,介绍一下带有参数的构造函数和通过构造器注入对象引用. 0. 目录 带有参数的构造函数 通过构造器注入 ...

  6. 在Android4.0中Contacts拨号盘界面剖析(源码)

      通过在 ViewPager 的适配器对象中,发现过一下三行代码 private DialpadFragment mDialpadFragment; private CallLogFragment ...

  7. 关于java的continue、break关键字用法

    一 明确两个概念 循环:是指按照规定次数重复执行某一操作的全过程:其关键语句有for. foreach.while.do while 迭代:是指循环过程中单次操作,1次循环由n次迭代构成 二 用法归纳 ...

  8. libevent的使用方法--回显服务器的简单实例

    #include <event.h> #include <sys/types.h> #include <sys/socket.h> #include <net ...

  9. CSS 背景图片的定位和缩放

    在 CSS 中,利用 background-image 属性我们可以指定元素的背景图片,例如: .example { background-image: url(image/some.png); ba ...

  10. C#开发的WebService使用JSON格式传递数据+Ajax测试

    [C#]  WebService 使用 JSON 格式傳遞筆記 + JQuery 測試 0 2 因為一些因素,必須改寫WebService,很傳統,但是很多公司還在用.. 因為XML 的關係,不想讓他 ...