diff --git a/problems/0062.不同路径.md b/problems/0062.不同路径.md
index e209abb1..efa85a03 100644
--- a/problems/0062.不同路径.md
+++ b/problems/0062.不同路径.md
@@ -347,6 +347,42 @@ var uniquePaths = function(m, n) {
};
```
+### C
+```c
+//初始化dp数组
+int **initDP(int m, int n) {
+ //动态开辟dp数组
+ int **dp = (int**)malloc(sizeof(int *) * m);
+ int i, j;
+ for(i = 0; i < m; ++i) {
+ dp[i] = (int *)malloc(sizeof(int) * n);
+ }
+
+ //从0,0到i,0只有一种走法,所以dp[i][0]都是1,同理dp[0][j]也是1
+ for(i = 0; i < m; ++i)
+ dp[i][0] = 1;
+ for(j = 0; j < n; ++j)
+ dp[0][j] = 1;
+ return dp;
+}
+
+int uniquePaths(int m, int n){
+ //dp数组,dp[i][j]代表从dp[0][0]到dp[i][j]有几种走法
+ int **dp = initDP(m, n);
+
+ int i, j;
+ //到达dp[i][j]只能从dp[i-1][j]和dp[i][j-1]出发
+ //dp[i][j] = dp[i-1][j] + dp[i][j-1]
+ for(i = 1; i < m; ++i) {
+ for(j = 1; j < n; ++j) {
+ dp[i][j] = dp[i-1][j] + dp[i][j-1];
+ }
+ }
+ int result = dp[m-1][n-1];
+ free(dp);
+ return result;
+}
+```
-----------------------
diff --git a/problems/0063.不同路径II.md b/problems/0063.不同路径II.md
index 490b6b5c..6f405d6a 100644
--- a/problems/0063.不同路径II.md
+++ b/problems/0063.不同路径II.md
@@ -333,6 +333,60 @@ var uniquePathsWithObstacles = function(obstacleGrid) {
};
```
+C
+```c
+//初始化dp数组
+int **initDP(int m, int n, int** obstacleGrid) {
+ int **dp = (int**)malloc(sizeof(int*) * m);
+ int i, j;
+ //初始化每一行数组
+ for(i = 0; i < m; ++i) {
+ dp[i] = (int*)malloc(sizeof(int) * n);
+ }
+
+ //先将第一行第一列设为0
+ for(i = 0; i < m; ++i) {
+ dp[i][0] = 0;
+ }
+ for(j = 0; j < n; ++j) {
+ dp[0][j] = 0;
+ }
+
+ //若碰到障碍,之后的都走不了。退出循环
+ for(i = 0; i < m; ++i) {
+ if(obstacleGrid[i][0]) {
+ break;
+ }
+ dp[i][0] = 1;
+ }
+ for(j = 0; j < n; ++j) {
+ if(obstacleGrid[0][j])
+ break;
+ dp[0][j] = 1;
+ }
+ return dp;
+}
+
+int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){
+ int m = obstacleGridSize, n = *obstacleGridColSize;
+ //初始化dp数组
+ int **dp = initDP(m, n, obstacleGrid);
+
+ int i, j;
+ for(i = 1; i < m; ++i) {
+ for(j = 1; j < n; ++j) {
+ //若当前i,j位置有障碍
+ if(obstacleGrid[i][j])
+ //路线不同
+ dp[i][j] = 0;
+ else
+ dp[i][j] = dp[i-1][j] + dp[i][j-1];
+ }
+ }
+ //返回最后终点的路径个数
+ return dp[m-1][n-1];
+}
+```
-----------------------
diff --git a/problems/0070.爬楼梯.md b/problems/0070.爬楼梯.md
index 97db670a..7f47a991 100644
--- a/problems/0070.爬楼梯.md
+++ b/problems/0070.爬楼梯.md
@@ -296,6 +296,48 @@ var climbStairs = function(n) {
};
```
+### C
+```c
+int climbStairs(int n){
+ //若n<=2,返回n
+ if(n <= 2)
+ return n;
+ //初始化dp数组,数组大小为n+1
+ int *dp = (int *)malloc(sizeof(int) * (n + 1));
+ dp[0] = 0, dp[1] = 1, dp[2] = 2;
+
+ //从前向后遍历数组,dp[i] = dp[i-1] + dp[i-2]
+ int i;
+ for(i = 3; i <= n; ++i) {
+ dp[i] = dp[i - 1] + dp[i - 2];
+ }
+ //返回dp[n]
+ return dp[n];
+}
+```
+
+优化空间复杂度:
+```c
+int climbStairs(int n){
+ //若n<=2,返回n
+ if(n <= 2)
+ return n;
+ //初始化dp数组,数组大小为3
+ int *dp = (int *)malloc(sizeof(int) * 3);
+ dp[1] = 1, dp[2] = 2;
+
+ //只记录前面两个台阶的状态
+ int i;
+ for(i = 3; i <= n; ++i) {
+ int sum = dp[1] + dp[2];
+ dp[1] = dp[2];
+ dp[2] = sum;
+ }
+ //返回dp[2]
+ return dp[2];
+}
+```
+
-----------------------
diff --git a/problems/0509.斐波那契数.md b/problems/0509.斐波那契数.md
index d8020d83..c6ce76c0 100644
--- a/problems/0509.斐波那契数.md
+++ b/problems/0509.斐波那契数.md
@@ -245,6 +245,38 @@ var fib = function(n) {
};
```
+### C
+动态规划:
+```c
+int fib(int n){
+ //当n <= 1时,返回n
+ if(n <= 1)
+ return n;
+ //动态开辟一个int数组,大小为n+1
+ int *dp = (int *)malloc(sizeof(int) * (n + 1));
+ //设置0号位为0,1号为为1
+ dp[0] = 0;
+ dp[1] = 1;
+
+ //从前向后遍历数组(i=2; i <= n; ++i),下标为n时的元素为dp[i-1] + dp[i-2]
+ int i;
+ for(i = 2; i <= n; ++i) {
+ dp[i] = dp[i - 1] + dp[i - 2];
+ }
+ return dp[n];
+}
+```
+
+递归实现:
+```c
+int fib(int n){
+ //若n小于等于1,返回n
+ if(n <= 1)
+ return n;
+ //否则返回fib(n-1) + fib(n-2)
+ return fib(n-1) + fib(n-2);
+}
+```
-----------------------
diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md
index 0009f06c..e94e4d24 100644
--- a/problems/0746.使用最小花费爬楼梯.md
+++ b/problems/0746.使用最小花费爬楼梯.md
@@ -266,5 +266,21 @@ var minCostClimbingStairs = function(cost) {
};
```
+### C
+```c
+int minCostClimbingStairs(int* cost, int costSize){
+ //开辟dp数组,大小为costSize
+ int *dp = (int *)malloc(sizeof(int) * costSize);
+ //初始化dp[0] = cost[0], dp[1] = cost[1]
+ dp[0] = cost[0], dp[1] = cost[1];
+
+ int i;
+ for(i = 2; i < costSize; ++i) {
+ dp[i] = (dp[i-1] < dp[i-2] ? dp[i-1] : dp[i-2]) + cost[i];
+ }
+ //选出倒数2层楼梯中较小的
+ return dp[i-1] < dp[i-2] ? dp[i-1] : dp[i-2];
+}
+```
-----------------------