骨骼动画原理

Reference

1. 浅谈骨骼动画技术原理(一):基本介绍 - 知乎 (zhihu.com)
2. 浅谈骨骼动画技术原理(二):正向动力学 - 知乎 (zhihu.com)
3. 浅谈骨骼动画技术原理(三):逆向动力学 - 知乎 (zhihu.com)
4. 浅谈骨骼动画技术原理(四):蒙皮与其他技术 - 知乎 (zhihu.com)

作者: 启思
文章链接:如上

正文

第一篇 浅谈骨骼动画技术原理(一):基本介绍

人物模型是由三角面 mesh 组成的。为了让人物动起来,一个最简单的想法是直接修改 mesh 的各个顶点的坐标,这带来了几个问题:

Read More

NavMesh寻路的原理

Reference

NavMesh背后的实现原理 - 知乎 (zhihu.com) 这篇文章主要是讲体素化

Navigation Mesh寻路算法 - 知乎 (zhihu.com)NavMesh的寻路原理

几何寻路:漏斗算法(Funnel Algorithm)-CSDN博客网格寻路的漏斗算法

正文

NavMesh 过程:

1.体素化 得到寻路所需的信息 比如是否能够行走 高度等等

一般来说,找到一个游戏角色的最佳路径至少需要3个阶段。在第一阶段,游戏世界被转换成几何表示,例如导航网格

Read More

279. 完全平方数

Problem: 279. 完全平方数

Code

[]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
int numSquares(int n) {
// dp[j]表示第j等于完全完全平方数的最少数量
vector<int> dp(n+1,INT_MAX);
// dp[0] = 0
dp[0] = 0;
// 组合问题 顺序无所谓
// 完全背包 顺序
for(int j=0;j<=n;j++){
// 物品是完全平方数
for(int i=1;i*i<=j;i++){
dp[j] = min(dp[j-i*i]+1,dp[j]);
}
}
return dp[n];
}
};

139. 单词拆分

Problem: 139. 单词拆分

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
//将单词划分 如果 0-j 和 j-i部分都可以在wordDict中找到
//那么长度为i的字符串可以由wordDic拼接而成
//dp[i] 表示长度为i的字符串可以由wordDic拼接而成
unordered_set<string> set(wordDict.begin(),wordDict.end());
vector<bool> dp(s.size()+1);
dp[0]=true;
for(int i=1;i<s.size()+1;i++) {
for(int j=0;j<i;j++) {//用j去划分成两部分
string sub = s.substr(j,i-j);//后面部分 s[j: i-1]
if(set.find(sub)!=set.end()&&dp[j]) {//前面部分 s[0: j]
dp[i]=true;
break; // dp[i] = true了,i长度的子串已经可以拆成单词了,不需要j继续划分子串了
}
}
}
return dp[s.size()];
}
};

123. 买卖股票的最佳时机 III

Problem: 123. 买卖股票的最佳时机 III

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 动态规划 本题与买卖股票的最佳时机II 唯一的区是本题只能买卖两次
// 且同时只能持有一支股票 递推公式 dp[i][0]
// 第i天第一次持有股票所得现金(选择最低的持有) dp[i][1]
// 第i天第一次卖出股票所得现金 dp[i][2]
// 第i天第二次卖出股票所得现金(选择最低的持有) dp[i][3]
// 第i天第二次卖出股票所得现金
vector<vector<int>> dp(prices.size(), vector<int>(5, 0));
// 初始化 dp[0][0] -= prices[0];dp[0][1] = 0;dp[0][2] -= prices[0];
// dp[0][3] = 0;
dp[0][1] -= prices[0];dp[0][3] -= prices[0];
for (int i = 1; i < prices.size(); i++) {
// 第一次买入
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
// 第一次卖出: 第一次持有+当前股价
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
// 第二次持有需要卖出第一次
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
// 第二次卖出: 第二次持有+当前股价
dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
}
return dp[prices.size()-1][4];
}
};

188. 买卖股票的最佳时机 IV

Problem: 188. 买卖股票的最佳时机 IV

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
//本题与123. 买卖股票的最佳时机 III 唯一的区别是本题可以k次买入
//通过123. 买卖股票的最佳时机 III我们已经可以发现一个规律了
//每次买入所得现金=max(之前买入所得现金,卖出上一次所得现金-当钱股价)
vector<vector<int>> dp(prices.size(), vector<int>(2*k+1, 0));
// 初始化 dp[0][1] -= prices[0];dp[0][3] -= prices[0];
for(int j=1;j<2*k;j+=2) dp[0][j] = -prices[0];
for (int i = 1; i < prices.size(); i++) {
// 第j次买入 dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
// 第j次卖出: 第j次持有+当前股价 dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
for(int j=1;j<2*k;j+=2) {
dp[i][j] = max(dp[i - 1][j ], dp[i - 1][j-1] - prices[i]);
dp[i][j+1] = max(dp[i - 1][j+ 1], dp[i - 1][j] + prices[i]);
}
}
return dp[prices.size()-1][2*k];
}
};