自己备查:如何优化算法--缓存
题目:
http://projecteuler.net/index.php?section=problems&id=164
projecteuler.net #164
How many 20 digit numbers n (without any leading zero) exist such that no three consecutive digits of n have a sum greater than 9?
使用简单算法,从高位到低位便利每种组合,慢的要死

List<int> number = new List<int>();
int count = 0;
public object Run()
{
for (int i = 0; i < 10; i++)
{
//number.Add(i);
Run2(1, i, 0);
//number.RemoveAt(0);
}
return count;
}
void Run2(int level, int last, int lastlast)
{
for (int i = 0, length = 9 - last - lastlast; i <= length; i++)
{
if (level == 2)
{
Console.WriteLine("" + lastlast + last + i);
}
//if (level > 1 && last + lastlast + i > 9)
// return;
if (level == 6)
{
count += 1;
return;
}
//number.Add(i);
Run2(level + 1, i, last);
//number.RemoveAt(level);
}
}
int count = 0;
public object Run()
{
for (int i = 0; i < 10; i++)
{
//number.Add(i);
Run2(1, i, 0);
//number.RemoveAt(0);
}
return count;
}
void Run2(int level, int last, int lastlast)
{
for (int i = 0, length = 9 - last - lastlast; i <= length; i++)
{
if (level == 2)
{
Console.WriteLine("" + lastlast + last + i);
}
//if (level > 1 && last + lastlast + i > 9)
// return;
if (level == 6)
{
count += 1;
return;
}
//number.Add(i);
Run2(level + 1, i, last);
//number.RemoveAt(level);
}
}
优化后,从低位到高位递增,每次缓存当位所有ok的数字以及对应的可能性供下位处理,时间复杂度O(n),瞬间完成

class Problem164 : IProblem
{
Dictionary<int, C> last = new Dictionary<int, C>();
Dictionary<int, C> current = new Dictionary<int, C>();
public object Run()
{
int l, ll;
for (int i = 0; i < 100; i++)
{
l = i / 10;
ll = i % 10;
if (l + ll < 10)
last.Add(i, new C(l, ll, 1));
}
return Run2(2);
}
public long Run2(int level)
{
int thisLevelBegin = (level == 19 ? 1 : 0);
current = new Dictionary<int, C>();
int l, ll, sum, newNum;
long count;
foreach (KeyValuePair<int, C> p in last)
{
l = p.Value.L;
ll = p.Value.LL;
count = p.Value.count;
sum = p.Value.sum;
for (int i = thisLevelBegin, length = 10 - sum; i < length; i++)
{
newNum = i * 10 + l;
if (!current.ContainsKey(newNum))
{
current.Add(newNum, new C(i, l, count));
}
else
{
current[newNum].count += count;
}
}
}
if (level == 19)
{
count = 0;
foreach (KeyValuePair<int, C> p in current)
{
count += p.Value.count;
}
return count;
}
last = current;
return Run2(level + 1);
}
}
class C
{
public int LL;
public int L;
public int sum;
public long count;
public C(int l, int ll, long c)
{
LL = ll;
L = l;
count = c;
sum = l + ll;
}
}
{
Dictionary<int, C> last = new Dictionary<int, C>();
Dictionary<int, C> current = new Dictionary<int, C>();
public object Run()
{
int l, ll;
for (int i = 0; i < 100; i++)
{
l = i / 10;
ll = i % 10;
if (l + ll < 10)
last.Add(i, new C(l, ll, 1));
}
return Run2(2);
}
public long Run2(int level)
{
int thisLevelBegin = (level == 19 ? 1 : 0);
current = new Dictionary<int, C>();
int l, ll, sum, newNum;
long count;
foreach (KeyValuePair<int, C> p in last)
{
l = p.Value.L;
ll = p.Value.LL;
count = p.Value.count;
sum = p.Value.sum;
for (int i = thisLevelBegin, length = 10 - sum; i < length; i++)
{
newNum = i * 10 + l;
if (!current.ContainsKey(newNum))
{
current.Add(newNum, new C(i, l, count));
}
else
{
current[newNum].count += count;
}
}
}
if (level == 19)
{
count = 0;
foreach (KeyValuePair<int, C> p in current)
{
count += p.Value.count;
}
return count;
}
last = current;
return Run2(level + 1);
}
}
class C
{
public int LL;
public int L;
public int sum;
public long count;
public C(int l, int ll, long c)
{
LL = ll;
L = l;
count = c;
sum = l + ll;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器