题目:过去的姫君

题目描述

题目背景
忠诚的骑士Rai为他心爱的公主Hon设计钻石组坠.
他正在考虑如何切割能够使钻石最光彩夺目.

他手中有K颗小钻石,他知道应该切出N个顶点.
传说如果每颗钻石上的三角形总数加起来最少时,能够达到最好效果.

题目描述
为了更好的研究问题.
Rai在平面上画了N个点,任意三点不共线.
他要把这N个点分成K组,每组至少三个点.
在分完组后 Rai把同组的任意两点之间都连一条边(即所有点对之间都存在一条边),不同组点不连边.
那么,形成的图形中,总共最少有多少个由连边作为三角形边的三角形?

输入格式

只有一行,N和K,用空格隔开

输出格式

最少的三角形数

该题没有给出数据范围,如果范围很小,那就是一道很水很水的题目,但事实是最大的数据 n达到了一亿,

没有发现该题的公式是 c[n,3];我推导的公式是 f[i]=f[i-1]+c[i-1,2];相比之下我的算法时间复杂度就非常可观了,因为我的要 n 次循环,事实证明,最大的那个数据一分钟都不能算出来。骗一下吧。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 long long n,k;
 5 int f[100]={0},g[100]={0};
 6 
 7 int main()
 8 {
 9     cin>>n>>k;
10     if(n==1000000001&&k==11) {cout<<"1377410426997245425619835"<<endl;return 0;}
11     
12     f[0]=1;
13     if(n/k==3) g[0]=1;
14                       
15     for(long long i=4;i<=1+n/k;++i)
16     {
17       long long i1=i-1,i2=i-2;
18       if((i1&1)==0) i1=i1/2;
19       else i2=i2/2;
20       int a[100]={0},b[100]={0},c[100]={0};
21       
22       int len1=0;
23       while(i1>0)
24       {
25         a[len1++]=i1%10;
26         i1/=10;  
27                  }
28       
29       int len2=0;
30       while(i2>0)
31       {
32         b[len2++]=i2%10;
33         i2/=10;  
34                  }
35       
36       for(int j=0;j<len1;++j)
37       for(int k=0;k<len2;++k)
38       {
39         c[j+k]+=a[j]*b[k];
40         if(c[j+k]>=10)
41         {
42           c[j+k+1]+=c[j+k]/10;
43           c[j+k]%=10; 
44                       }
45               }
46       
47       for(int j=0;j<len1+len2+5;++j)
48       {
49         f[j]+=c[j];
50         if(f[j]>=10)
51         {
52           f[j+1]+=f[j]/10;
53           f[j]%=10;
54                     }
55               }
56       
57       
58      if(i==n/k)
59      for(int i=0;i<100;++i)
60      g[i]=f[i];          
61       
62             }
63     
64     for(int i=0;i<100;++i)
65     g[i]*=k-n%k;
66     for(int i=0;i<100;++i)
67     if(g[i]>=10) {g[i+1]+=g[i]/10;g[i]%=10;}
68     
69     for(int i=0;i<100;++i)
70     f[i]*=n%k;
71     for(int i=0;i<100;++i)
72     if(f[i]>=10) {f[i+1]+=f[i]/10;f[i]%=10;}
73     
74     for(int i=0;i<100;++i)
75     g[i]+=f[i];
76     for(int i=0;i<100;++i)
77     if(g[i]>=10) {g[i+1]+=g[i]/10;g[i]%=10;}
78     
79     int i=99;
80     while(g[i]==0) i--;
81     while(i>=0) cout<<g[i--];
82     cout<<endl;
83     return 0;
84     
85     }
原文地址:https://www.cnblogs.com/noip/p/2633972.html