【dp入门题】【跟着14练dp吧...囧】
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吧...囧】的更多相关文章
- poj 3254 状压dp入门题
1.poj 3254 Corn Fields 状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...
- POJ 2342 树形DP入门题
有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...
- (树形DP入门题)Anniversary party(没有上司的舞会) HDU - 1520
题意: 有个公司要举行一场晚会.为了让到会的每个人不受他的直接上司约束而能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会再邀请他的直接的上司,但该人的上司的上司,上司的上司的上司等都可以邀请. ...
- UVA 674 Coin Change 换硬币 经典dp入门题
题意:有1,5,10,25,50五种硬币,给出一个数字,问又几种凑钱的方式能凑出这个数. 经典的dp题...可以递推也可以记忆化搜索... 我个人比较喜欢记忆化搜索,递推不是很熟练. 记忆化搜索:很白 ...
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
[HDU 3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...
- HDU 2089 不要62【数位DP入门题】
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- poj 2955 区间dp入门题
第一道自己做出来的区间dp题,兴奋ing,虽然说这题并不难. 从后向前考虑: 状态转移方程:dp[i][j]=dp[i+1][j](i<=j<len); dp[i][j]=Max(dp[i ...
- 数位DP入门题——[hdu2089]不要62
数位DP是我的噩梦. 现在初三了,却没AC过数位DP的题目. 感觉数位DP都是毒瘤-- 题目 hdu不用登录也可以进去,所以就不把题目copy到这里来了. 题目大意 求区间[n,m][n,m][n,m ...
- 洛谷 P1879 玉米田(状压DP入门题)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int M,N; int plant[maxn][maxn];/ ...
随机推荐
- 问题-PopupMenu是哪个控件调用弹出的?
相关资料: http://bbs.csdn.net/topics/310195683 问题现象:今天有朋友问我个简单的问题,在多个Edit上弹出菜单,怎么判断是哪个Edit调用的.我想了想这个我还真不 ...
- DBMS_ERRLOG记录DML错误日志(二)
上一篇简单介绍了DML记录语句的限制,虽然所有的例子都是利用INSERT语句,但是LOG ERRORS语句并没有这个限制,UPDATE.DELETE和MERGE都可以使用这个语句.下面要说的就是这篇的 ...
- Spring EL ternary operator (if-then-else) example
Spring EL supports ternary operator , perform "if then else" conditional checking. For exa ...
- IMAQ Flatten Image to String VI的参数设置对比
无压缩 jpeg压缩 无损二元包装 仅JPEG压缩时有效 平化类型(指定字符串中存储什么类型的数据) None JPEG PACKED BINARY Quality Image Image and ...
- jquery easyui中的dialog拖动超出浏览器问题解决办法
juqery easyui当鼠标点着拖动超出浏览器后,就回不来了,拉不下的问题: //控制dialog超出浏览器回到原来的地方 var default_left; var default_top;// ...
- Umbraco官方技术文档 中文翻译
Umbraco 官方技术文档中文翻译 http://blog.csdn.net/u014183619/article/details/51919973 http://www.cnblogs.com/m ...
- PHP- Windows无法在本地计算机启动Apache的解决方法
装好了WAMP,开始可以进行我的PHP学习了.可是装后却打不开locahost. 百度后如下解决了:"Windows不能在本地计算机启动Apache2.有关更多信息,查阅系统事件日志.如果这 ...
- ThinkPHP3.1.3的单字母函数汇总
A函数: 用于实例化Action 格式:[项目://][分组/]模块 /** * A函数用于实例化Action 格式:[项目://][分组/]模块 * @param string $name Acti ...
- MATLAB代码
clear;clc%%%%%%%%%%%%方程里的参量%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%alpha=0.5;beta=0.5;%%% ...
- Hash Table构建
get-item e:\test\* |format-table @{name="aa";expression={$_.name.tostring().split(".& ...