基本思想与策略:
基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。
由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。

状态抓换方程:
dp[i][j] = a[i][j] + max(dp[i+1][j], dp[i+1][j+1]); //dp[i][j]表示从(i,j)位置开始走的最大和
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
第二题:HDU 2602(01背包问题)
Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 38897 Accepted Submission(s): 16122
Problem Description
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?
Input
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 2
31).
Sample Input
1 5 10 1 2 3 4 5 5 4 3 2 1
Sample Output
题意:
第一行是测试组数t,接下来是n,m分别表示物品总数和背包最大载重,接下来的两行分别是价值和重量。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
for(int j = 0; j <= m; j++){ //j表示容量
if(weight[i] <= j){
dp[i][j] = Max(dp[i - 1][j - weight[i]] + value[i], dp[i-1][j]); //dp[i][j]表示装入前i个物体在j体积下的最大价值
}
else
dp[i][j] = dp[i-1][j];
}
}
}
int main(){
#ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
int t;
sf(t);
while(t--){
Into();
slove(); //核心步骤
pf(dp[n][m]);
}
return 0;
}
还有一道题是易彰彪出的捡死鱼问题:
yzb的鱼
时间限制(C/C++):3000MS/6000MS 运行内存限制:65536KByte
总提交:61 测试通过:13
描述
有一天yzb去澳大利亚,忽然天上掉下鱼。
说来yzb的人品实在是太好了,鱼别处都不掉,就掉落在他身旁的10米内。yzb马上找来鱼筐去接,而掉在地上的鱼yzb是不会要的。
但由于yzb运动基因不发达,每秒种只有在移动不超过一米的范围内接住坠落的鱼。
为了使问题简化,假设在接下来的一段时间里,鱼都掉落在0-10这11个位置。
开始时yzb站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的鱼。问yzb最多可能接到多少条鱼?
输入
输入数据有多组。每组数据的第一行为以正整数n(0 在结下来的n行中,每行有两个整数x,T(0 同一秒钟在同一点上可能掉下多个鱼。n=0时输入结束。
输出
每一组输入数据对应一行输出。输出一个整数m,表示yzb最多可能接到m条鱼。
样例输入
6
5 1
4 1
6 1
7 2
7 2
8 3
0
样例输出
4
分析:

代码:
递归:像我这样的低智商玩家一开始只能想到这个。。。。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
循环:别人优化了一下,自己写了一遍
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
用循环比用递归快了很多了。
最后一道题,王教授出在oj上的题。
最长不降奇偶交替子列
时间限制(C/C++):1000MS/3000MS 运行内存限制:65536KByte
总提交:227 测试通过:38
描述
一个序列中选择其中的若干个,保持以前顺序生成的新的序列称为原序列的子列,如果子列中每相邻两个元素的奇偶性交替出现,则称这个子列为奇偶交替子列。你的任务是:对于给定的序列, 计算出其最长单调不降奇偶交替子列的长度。
输入
输入的第1行是一个整数n,在[1, 20]之间,表示测试用例的数量。对于每一个测试用例, 第一行是一个整数mi,表示该测试用例序列中数据的数量,在[2, 200]中。后面紧跟mi行,每一行是该序列的一个数据,每个数据在区间[-10000, 10000]之中。
输出
对于每个测试用例,输出一行,只包含一个整数,表示相应测试用例最长不降奇偶交替子列的长度。
样例输入
5
4
-10
-5
-8
-2
8
9
-7
-9
-3
-13
-15
7
7
1
-6
6
-17
-15
-8
-2
-7
-8
2
-7
0
样例输出
3
1
1
3
2
分析:想了想自己模拟了一遍画出来大概是棵树的结构,至于是什么树我也不知道,还没学到。

字好丑!
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
然后是一道poj上的题目:
Football
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 3780 |
|
Accepted: 1934 |
Description
Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2n. In each round of the tournament, all teams still in the tournament are placed in a list in order of increasing index. Then, the first team in the list plays the second team, the third team plays the fourth team, etc. The winners of these matches advance to the next round, and the losers are eliminated. After n rounds, only one team remains undefeated; this team is declared the winner.
Given a matrix P = [pij] such that pij is the probability that team i will beat team j in a match determine which team is most likely to win the tournament.
Input
The input test file will contain multiple test cases. Each test case will begin with a single line containing n (1 ≤ n ≤ 7). The next 2n lines each contain 2n values; here, the jth value on the ith line represents pij. The matrix P will satisfy the constraints that pij = 1.0 − pji for all i ≠ j, and pii = 0.0 for all i. The end-of-file is denoted by a single line containing the number −1. Note that each of the matrix entries in this problem is given as a floating-point value. To avoid precision problems, make sure that you use either the double
data type instead of float
.
Output
The output file should contain a single line for each test case indicating the number of the team most likely to win. To prevent floating-point precision issues, it is guaranteed that the difference in win probability for the top two teams will be at least 0.01.
Sample Input
2
0.0 0.1 0.2 0.3
0.9 0.0 0.4 0.5
0.8 0.6 0.0 0.6
0.7 0.5 0.4 0.0
-1
Sample Output
2
Hint
In the test case above, teams 1 and 2 and teams 3 and 4 play against each other in the first round; the winners of each match then play to determine the winner of the tournament. The probability that team 2 wins the tournament in this case is:
P(2 wins) |
= P(2 beats 1)P(3 beats 4)P(2 beats 3) + P(2 beats 1)P(4 beats 3)P(2 beats 4) = p21p34p23 + p21p43p24 = 0.9 · 0.6 · 0.4 + 0.9 · 0.4 · 0.5 = 0.396. |
The next most likely team to win is team 3, with a 0.372 probability of winning the tournament.
分析:
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include