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. 问题-PopupMenu是哪个控件调用弹出的?

    相关资料: http://bbs.csdn.net/topics/310195683 问题现象:今天有朋友问我个简单的问题,在多个Edit上弹出菜单,怎么判断是哪个Edit调用的.我想了想这个我还真不 ...

  2. DBMS_ERRLOG记录DML错误日志(二)

    上一篇简单介绍了DML记录语句的限制,虽然所有的例子都是利用INSERT语句,但是LOG ERRORS语句并没有这个限制,UPDATE.DELETE和MERGE都可以使用这个语句.下面要说的就是这篇的 ...

  3. Spring EL ternary operator (if-then-else) example

    Spring EL supports ternary operator , perform "if then else" conditional checking. For exa ...

  4. IMAQ Flatten Image to String VI的参数设置对比

    无压缩 jpeg压缩 无损二元包装 仅JPEG压缩时有效 平化类型(指定字符串中存储什么类型的数据)   None JPEG PACKED BINARY Quality Image Image and ...

  5. jquery easyui中的dialog拖动超出浏览器问题解决办法

    juqery easyui当鼠标点着拖动超出浏览器后,就回不来了,拉不下的问题: //控制dialog超出浏览器回到原来的地方 var default_left; var default_top;// ...

  6. Umbraco官方技术文档 中文翻译

    Umbraco 官方技术文档中文翻译 http://blog.csdn.net/u014183619/article/details/51919973 http://www.cnblogs.com/m ...

  7. PHP- Windows无法在本地计算机启动Apache的解决方法

    装好了WAMP,开始可以进行我的PHP学习了.可是装后却打不开locahost. 百度后如下解决了:"Windows不能在本地计算机启动Apache2.有关更多信息,查阅系统事件日志.如果这 ...

  8. ThinkPHP3.1.3的单字母函数汇总

    A函数: 用于实例化Action 格式:[项目://][分组/]模块 /** * A函数用于实例化Action 格式:[项目://][分组/]模块 * @param string $name Acti ...

  9. MATLAB代码

    clear;clc%%%%%%%%%%%%方程里的参量%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%alpha=0.5;beta=0.5;%%% ...

  10. Hash Table构建

    get-item e:\test\* |format-table @{name="aa";expression={$_.name.tostring().split(".& ...