自己备查:如何优化算法--缓存

 题目:

 

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?

 

使用简单算法,从高位到低位便利每种组合,慢的要死

 

View Code
        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);
            }
        }

 

优化后,从低位到高位递增,每次缓存当位所有ok的数字以及对应的可能性供下位处理,时间复杂度O(n),瞬间完成

View Code
    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;
        }
    }

 

 

 

 

 

 

posted on 2011-03-18 11:21  右耳纹金刀  阅读(375)  评论(0编辑  收藏  举报

导航