1.剪绳子
贪心算法,将绳子尽可能的剪成3,余数只可能为0,1,2。当余数为1时,应该与前一个3结合成4,因为4>3*1。
class Solution {
public:
int cuttingRope(int n) {
if(n<4) return n-1;
int res=1;
while(n>=3)
{
res*=3;
n-=3;
}
//余数有0,1,2三种情况
if(n==1) return (res/3)*4;
else if(n==2) return res*2;
else return res;
}
};
2.和为s的连续正数序列
滑动窗口
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
int i=1,j=2,sum=3;
vector<vector<int>> result;
while(i<j)
{
if(sum==target)
{
vector<int> path;
for(int m=i;m<=j;m++)
{
path.push_back(m);
}
result.push_back(path);
}
if(sum>=target)
{
sum-=i;
i++;
}
else
{
j++;
sum+=j;
}
}
return result;
}
};
圆圈中最后剩下的数字
n个数组成一个圆圈,每次删除第m个数
约瑟夫环问题,动态规划
假定输入n,m记为【n,m问题】,设剩下的数为f(n);
则有【n-1,m问题】:数字环0,1,2...n-2,解为f(n-1)。
对于【n,m问题】,首轮删除的数字为(m-1)%n(对n取模是因为m有可能大于n),删除后的数字环从m%n开始,设t=m%n,可得数字环:t,t+1,t+2,...,0,1,2...t-3,t-2
于是有个对应关系:
0 | t+0 |
1 | t+1 |
... | ... |
n-2 | t-2 |
因此可得递推关系:
如果【n-1,m】问题某个数字为x,那么对应的【n,m】问题的数为(x+t)%n。
f(n)=(f(n-1)+t)%n=(f(n-1)+m)%n