随笔分类 - DP
摘要:题目:http://poj.org/problem?id=3661题意:一头牛,给出他运动的时间 ts,在运动时间内,它可以选择跑步,也可以选择休息,如果他跑步疲劳值 +1,如果休息疲劳值 -1,如果它在休息,那么必须疲劳值为0时才能跑步,问到第N秒且疲劳值为0时,牛可以跑得最远距离dp[i][j] 表示 在第 i 秒时 疲劳值为 j 时牛跑的最远距离,那么方程就是 dp[i][j] = dp[i - 1][j - 1] + dis[i] (如果在第 i 秒跑步)dp[i][0] = Max(dp[i][0],dp[i - j][j]) (if( i - j >= j),初始化 dp[i
阅读全文
摘要:题目:http://poj.org/problem?id=1088记忆化搜索,dp[r][c] = max(dp[r - 1][c] , dp[r + 1][c] , dp[r][c - 1] , dp[r][c + 1]) + 1 ( if (题目给的条件满足))View Code 1 using namespace std; 2 typedef long long ll; 3 const int N = 110; 4 int map[N][N]; 5 int dp[N][N]; 6 int n,m; 7 int dfs(int r, int c) // 四个方向深搜 8 { 9 ...
阅读全文
摘要:两道简单的 dp题目题目:http://poj.org/problem?id=1159给一个字符串添加字符,使字符串变成回文串,很简单的一个dp,不过还是MLE了一次,改成了滚动数组就可以了View Code 1 const int N = 5010; 2 int dp[2][N]; 3 char str[N]; 4 int main() 5 { 6 int i,j,n; 7 //freopen("data.txt","r",stdin); 8 while(scanf("%d",&n) != EOF) 9 {10 getcha
阅读全文
摘要:状态压缩dp,感觉还是不清晰,虽说就两种状态 0 1,但是感觉变化太多了,而且状态转移也不好想题目:http://poj.org/problem?id=3254题意:给出 N * M的图,上面只有 0 或者 1两种情况,如果是 1 表示这里可以放牛,如果是 0 表示不可以放牛,而且牛是不可以相邻的,问在这片区域内最多有多少种放牛的方案很简单的一个状态压缩 按给出的样例来说先看第一行 (1 表示该位置有牛,0 表示该位置没有牛)可以用二进制串来表示牛的放置情况0 0 0 (0) 0 0 1(1) 0 1 0 (2) 1 0 0(4) 1 0 1(5) 也就是题目中给的第一行最多有这五种情况,分.
阅读全文
摘要:两道树形 dp题目:http://poj.org/problem?id=2057题意:蜗牛的房子丢在了树上的某个节点上(每个节点的可能性相同),有些节点上有虫子,可以告诉蜗牛它的房子是不是在以这个节点为根的子树上,蜗牛找到房子的最小数学期望值是多少。首先期望是:找到房子走的步数 / 叶子节点的总数。叶子节点总数是固定的,那么走的步数越少,期望值也就越小,因为一个节点可能有多个孩子,从不同的孩子开始走得到的步数是不同的,优先选择哪个孩子这里用了贪心,解释见代码。定义三个数组su[N] // su [i] 表示走到以 节点 i 为根的子树成功找到房子的步数 如果 i 是叶子节点那么 su [i]
阅读全文
摘要:题目:http://poj.org/problem?id=3280题意:给出一个字符串,可以增加 或 删除 个别字符,增加和删除都是有权重的,求在最小权重下把给的字符串变成回文串感觉类似于求最长公共子序列的,把每个字符串增加和删除的权重存入两个数组,当前后对称的两个字符串相等时 dp[j][k] = dp[j + 1][k - 1],否则 dp[j][k] = min( min(dp[j+1][k]+add[str[j]-'a'], dp[j][k-1]+add[str[k]-'a']), min(dp[j+1][k]+sub[str[j]-'a'
阅读全文
摘要:一道简单的求解最长上升子序列的问题。感觉这道题的巧妙之处就是在查找最长上升子序列的时候用到了变形的二分查找。很是巧妙,因为一般的找上升子序列的方法,用于这道题是超时的。巧妙的代码为: else { int l=1; int h=max; while(l<=h) { int mid=(l+h)/2; if(flag[mid]>a[i].r) ...
阅读全文
摘要:一开始我还在那里想用组合公式做,就是把所有的从连续为M 到N 所有的可能都写一下,可是根本都不行。一个是数太大,一个是情况太多了。今天看见AV_VON的解题报告,原来,原来是DP啊 我们根据他的数据要求开一个数组,大小为2001, dp[2001]。这个数组用来存放子问题的解,比如dp[i]就代表投完第i个硬币时,已有连续m个正面的概率。具体假如m是2,dp[0],dp[1]肯定0,因为投币0次或1次不可能出现连续两次正面。分三种情况讨论:1. n小于m,即dp数组下标i要小于m的时候,概率值都为0,原因如上所述。2. 下标i等于m,也就是说n等m,投多少次刚好多少次是正面,这个概率是0.5的
阅读全文

浙公网安备 33010602011771号