1. Burst Balloons
题目:
有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i后,气球 left 和气球 right 就变成了相邻的气球。
求所能获得硬币的最大数量。
说明:
你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。
0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
示例:
输入:
[3,1,5,8]
输出:
167
解释:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 315 + 358 + 138 + 181 = 167
思路:
区间dp,dp[i][j] 代表i,j之间最大值,转移方程就是 dp[i][j] = max(dp[i][j], dp[i][m-1]+dp[m+1][j]+a[m]*a[l-1]*a[r+1])一开始自己写的时候转移写错了,注意dp[i][j]代表的是i,j之间的最大值,枚举m的时候乘以的应该是l-1,跟r+1的值,因为m消失了,他们并不会消失,而不是乘以l跟r的值,如果那样的话dp[i][j]的意义就不对了
代码:
class Solution {
int dp[507][507];
public:
int maxCoins(vector<int>& nums) {
int n = nums.size();
int b[n+10];
b[0] = b[n+1] = 1;
for(int i = 1; i <= n; i++) b[i] = nums[i-1];
for(int len = 1; len <= n; len++)
{
for(int l = 1; len+l-1 <= n; l++)
{
int r = len+l-1;
for(int m = l; m <= r; m++)
dp[l][r] = max(dp[l][r], b[l-1]*b[r+1]*b[m]+dp[l][m-1]+dp[m+1][r]);
// cout << l << ' ' << r << ' ' << dp[l][r] << endl;
}
}
return dp[1][n];
}
};
2. Max Points on a Line
题目:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
思路:
这题最直接的想法枚举两个点确定直线,然后判断有多少个点在这个直线上。再就是枚举两个点的时候,通过map来记录他们的斜率的个数,斜率相同就+1, 斜率要注意没有斜率的时候,可以用一个inf记录,但是还要特判。比较好的思路就是维护一个字符串:dx_dy的格式,同时dx,dy要是最简的,所以都除以他们的gcd就好。
代码:
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints