在线等待 算法问题

wwweather 2009-09-13 09:36:32
有8个变量a1=50,a2=40,a3=30,a4=50,a5=50,a6=50,a7=50,a8=50,让每个变量从0到它的最大值开始循环,求a1+a2+a3+a4+a5+a6+a7+a8=116,所有这些组合的列表,效率要高,麻烦写一段c的程序
...全文
497 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
xzh_endless 2009-09-23
  • 打赏
  • 举报
回复
以前不知道在线等是什么含义,突然一天我明白了。
笔试的时候一哥们掏出手机,然后按了一会儿,继续做题,不久,答案到手。。。。。。。
惊的我目瞪口呆。。。
li_x1979 2009-09-23
  • 打赏
  • 举报
回复
感觉没什么算法可言,完全是在考怎么写代码。

public void AddTo116()
{
for(int a1 = 0;a1 <= 50;a1++)
for(int a2 = 0;a2 <= 40;a2++)
{
int sum2 = a1 + a2; //前两个数的和
int max3 = 30 < (116 - sum2) ? 30 : (116 - sum2); //a3的最大取值
for (int a3 = 0; a3 <= max3; a3++)
{
int sum3 = sum2 + a3; //前三个数的和
int max4 = 50 < (116 - sum3) ? 50 : (116 - sum3); //a4的最大取值
for (int a4 = 0; a4 <= max4; a4++)
{
int sum4 = sum3 + a4; //前四个数的和
int max5 = 50 < (116 - sum4) ? 50 : (116 - sum4); //a5的最大取值
for (int a5 = 0; a5 <= max5; a5++)
{
int sum5 = sum4 + a5; //前五个数的和
int max6 = 50 < (116 - sum5) ? 50 : (116 - sum5); //a6的最大取值
for (int a6 = 0; a6 <= max6; a6++)
{
int sum6 = sum5 + a6; //前六个数的和
int max7 = 50 < (116 - sum6) ? 50 : (116 - sum6); //a7的最大取值
for (int a7 = 0; a7 <= max7; a7++)
{
int sum7 = sum6 + a7; //前七个数的和
int a8 = 116 - sum7; //a8的值由前七个数唯一确定

//如果a8有效,则找到
if (a8 >= 0 && a8 <= 50)
{
Console.WriteLine(a1 + " " + a2 + " " + a3 + " " + a4 + " " + a5 + " " + a6 + " " + a7 + " " + a8);
}

}
}
}
}
}
}
}
feiyangdn 2009-09-22
  • 打赏
  • 举报
回复
如当CompIndex = 2时,由小于等于50和40两个数进行相加,CurrEqNum的结果
等于0的一个,等于1的两个,等于3的3个,以此类推......
[0] 1
[1] 2
[2] 3
[3] 4
[4] 5
[5] 6
[6] 7
[7] 8
[8] 9
[9] 10
[10] 11
[11] 12
[12] 13
[13] 14
[14] 15
[15] 16
[16] 17
[17] 18
[18] 19
[19] 20
[20] 21
[21] 22
[22] 23
[23] 24
[24] 25
[25] 26
[26] 27
[27] 28
[28] 29
[29] 30
[30] 31
[31] 32
[32] 33
[33] 34
[34] 35
[35] 36
[36] 37
[37] 38
[38] 39
[39] 40
[40] 41
[41] 41
[42] 41
[43] 41
[44] 41
[45] 41
[46] 41
[47] 41
[48] 41
[49] 41
[50] 41
[51] 40
[52] 39
[53] 38
[54] 37
[55] 36
[56] 35
[57] 34
[58] 33
[59] 32
[60] 31
[61] 30
[62] 29
[63] 28
[64] 27
[65] 26
[66] 25
[67] 24
[68] 23
[69] 22
[70] 21
[71] 20
[72] 19
[73] 18
[74] 17
[75] 16
[76] 15
[77] 14
[78] 13
[79] 12
[80] 11
[81] 10
[82] 9
[83] 8
[84] 7
[85] 6
[86] 5
[87] 4
[88] 3
[89] 2
[90] 1
[91] 0
后面全是0


huangbo0603 2009-09-22
  • 打赏
  • 举报
回复
学习学习!
feiyangdn 2009-09-22
  • 打赏
  • 举报
回复
只算组数,很简单很快速,最大循环体为8*116

CurrEqNum[AddIndex]----表示当前总和为AddIndex的组数,所谓当前就是只有CompIndex组数字时。


#include <stdio.h>

#define MAX_ADD 127
#define NADD 8
__int64 EqAdd(int Eq, int AddArray[NADD], int ArrayNum)
{
int CompArray[NADD+1];
__int64 CurrEqNum[MAX_ADD+1];
__int64 CurrEqNumSave[MAX_ADD+1];
int CompIndex = 0;
int AddIndex = 0;
if (ArrayNum > NADD || Eq > MAX_ADD)
{
return 0;
}
for (CompIndex = 0; CompIndex <= ArrayNum; CompIndex++)
{
CompArray[CompIndex] = 0;

}
for (AddIndex = 0; AddIndex <= Eq; AddIndex++)
{
CurrEqNum[AddIndex] = 0;
}
CurrEqNum[0] = 1;
for (CompIndex = 0; CompIndex < ArrayNum; CompIndex++)
{
for (AddIndex = 0; AddIndex <= Eq; AddIndex++)
{
if (AddIndex == 113)
{
AddIndex = 113;
}
CurrEqNumSave[AddIndex] = CurrEqNum[AddIndex];
if (AddIndex > 0)
{
CurrEqNum[AddIndex] += CurrEqNum[AddIndex-1];
}
if (AddIndex - AddArray[CompIndex] > 0)
{
CurrEqNum[AddIndex] -= CurrEqNumSave[AddIndex - AddArray[CompIndex] -1];
}
}
}
return CurrEqNum[Eq];
}

void main()
{
int AddArray[NADD] = {50,40,30,50,50,50,50,50};//不允许取0
printf("\n总组数为%I64d\n", EqAdd(116, AddArray, 8));
}



总组数为49892973204
Press any key to continue
chj_2003 2009-09-20
  • 打赏
  • 举报
回复
你问的问题根本不用八个循环,你可以构造一颗九层的二叉树。构造方法如下:
1:第i个元素,与树的第i+1层对应。
2:左子树的值等于父节点,右子树的值等于父节点的值加上对应元素的值。也就是说,做子树表示不加对应数,右子树表示加对应的数。这样不但可以求得所有可能,而且会避免一些不必要的加法用算。
青蛙果果 2009-09-18
  • 打赏
  • 举报
回复
求种类数的话 是不是相当于数的拆分?
fenix124 2009-09-16
  • 打赏
  • 举报
回复
只算个数有数学方法的
zb_fly 2009-09-15
  • 打赏
  • 举报
回复
thinking,
sljsuper 2009-09-15
  • 打赏
  • 举报
回复
哪个SB会出这个题目
xiaoxiassk 2009-09-15
  • 打赏
  • 举报
回复
强悍!
绿色夹克衫 2009-09-14
  • 打赏
  • 举报
回复
发现算某些情况的时候,速度很慢,加了一个简单的累加剪枝
算了一下另一个帖子里的打靶问题,不知道是否算对了

http://topic.csdn.net/u/20090914/09/ae5a344e-efbf-482c-8cb2-dc8a1341ef81.html

using System;

namespace ConsoleApplication5
{
class Program
{
static long[,] Counter;
static int[] upper;
static int[] accumlation;

static void Main(string[] args)
{
int Sum = 90;
upper = new int[] { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 };
accumlation = new int[upper.Length + 1];

for (int i = upper.Length - 1; i>=0 ; i--)
accumlation[i] = accumlation[i + 1] + upper[i];

Counter = new long[Sum + 1,upper.Length];
Console.WriteLine(Calculate(Sum, 0));
}

static long Calculate(int sum,int index)
{
if (sum == 0 || sum == accumlation[index])
return 1;

if (index >= upper.Length || sum > accumlation[index])
return 0;

if(Counter[sum,index] > 0)
return Counter[sum, index];

for (int i = 0; i <= Math.Min(upper[index],sum); i++)
Counter[sum, index] += Calculate(sum - i, index + 1);

return Counter[sum, index];
}
}
}
绿色夹克衫 2009-09-14
  • 打赏
  • 举报
回复
如果是求全部的组合,确实没有意义。只是输出,恐怕就要很多年。

如果求个数的话,可以用DP,程序没有仔细检验,大概就是这个意思吧!


using System;

namespace ConsoleApplication5
{
class Program
{
static long[,] Counter;
static int[] upper;

static void Main(string[] args)
{
int Sum = 116;
upper = new int[] { 30, 40, 50, 50, 50, 50, 50, 50 };
Counter = new long[Sum + 1,upper.Length];
Console.WriteLine(Calculate(Sum, 0));
}

static long Calculate(int sum,int index)
{
if(sum == 0)
return 1;
if(index >= upper.Length)
return 0;

if(Counter[sum,index] > 0)
return Counter[sum, index];

for (int i = 0; i <= Math.Min(upper[index],sum); i++)
Counter[sum, index] += Calculate(sum - i, index + 1);

return Counter[sum, index];
}
}
}


linren 2009-09-14
  • 打赏
  • 举报
回复
【程序】
#include <stdio.h>
#include <windows.h>
#include <time.h>

__int64 c=0;
__int64 d=0;

void subfun(LPVOID sc){
int a[8]={0};
int b[8]={0};
int u[8]={50,50,50,50,50,30,40,50};
int x,y;

for(a[0]=1;a[0]<=50;a[0]=a[0]+2){//a1
printf(" sub thrd [%d/50]\n",a[0]);
b[0]=a[0];
for(a[1]=0;a[1]<=50;a[1]++){//a4
printf(" sub thrd [%d/50]\t[%d/50]\n",a[0],a[1]);
b[1]=b[0]+a[1];
if(b[1]>116) break;
for(a[2]=0;a[2]<=50;a[2]++){//a5
b[2]=b[1]+a[2];
if(b[2]>116) break;
for(a[3]=0;a[3]<=50;a[3]++){//a6
b[3]=b[2]+a[3];
if(b[3]>116) break;
for(a[4]=0;a[4]<=50;a[4]++){//a7
b[4]=b[3]+a[4];
if(b[4]>116) break;
if(b[4]<26) x=26-b[4];
else x=0;
for(a[5]=x;a[5]<=30;a[5]++){//a3
b[5]=b[4]+a[5];
if(b[5]>116) break;
if(b[5]<66) y=66-b[5];
else y=0;
for(a[6]=y;a[6]<=40;a[6]++){//a2
if(b[5]+a[6]>116) break;
//a[7]=116-b[6];//a8
d++;
}
}
}
}
}
}
}
}

int main(){
int a[8]={0};
int b[8]={0};
int u[8]={50,50,50,50,50,30,40,50};
char s[100];
HANDLE thrd;
int t1,t2;
int x,y;

t1=time(NULL);

thrd=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)subfun,NULL,0,NULL);


for(a[0]=0;a[0]<=50;a[0]=a[0]+2){//a1 0~50
printf("main thrd [%d/50]\n",a[0]);
b[0]=a[0];
for(a[1]=0;a[1]<=50;a[1]++){//a4 0~50
printf("main thrd [%d/50]\t[%d/50]\n",a[0],a[1]);
b[1]=b[0]+a[1];
if(b[1]>116) break;
for(a[2]=0;a[2]<=50;a[2]++){//a5
b[2]=b[1]+a[2];
if(b[2]>116) break;
for(a[3]=0;a[3]<=50;a[3]++){//a6
b[3]=b[2]+a[3];
if(b[3]>116) break;
for(a[4]=0;a[4]<=50;a[4]++){//a7
b[4]=b[3]+a[4];
if(b[4]>116) break;
if(b[4]<26) x=26-b[4];
else x=0;
for(a[5]=x;a[5]<=30;a[5]++){//a3
b[5]=b[4]+a[5];
if(b[5]>116) break;
if(b[5]<66) y=66-b[5];
else y=0;
for(a[6]=y;a[6]<=40;a[6]++){//a2
if(b[5]+a[6]>116) break;
//a[7]=116-b[6];//a8
c++;
}
}
}
}
}
}
}
WaitForSingleObject(thrd,INFINITE);

printf("c: \t%I64d\n",c);
printf("d: \t%I64d\n",d);
c=c+d;

t2=time(NULL);

printf("number: %I64d\n",c);
printf("use time: %d:%02d\n",(t2-t1)/60,(t2-t1)%60);

sprintf(s,"number:\n%I64d\n",c);
sprintf(s,"%suse time: %d:%02d\n",s,(t2-t1)/60,(t2-t1)%60);
MessageBox(NULL,s,"number",0);
return 0;
}

【运行结果】


【说明】
对18楼的程序进行了优化……
最后是节省了6分钟的时间……
linren 2009-09-14
  • 打赏
  • 举报
回复
(上接20楼)

给20楼再增加一个限制条件……
即a5, a6, a7, a8彼此需要互不相等……

然后再用方法(3)进行计算……

【程序】
#include <stdio.h>

void fun1(){
int a[4]={0};
int x=0;
for(a[0]=0;a[0]<=50;a[0]++){
for(a[1]=0;a[1]<=50;a[1]++){
if(a[1]==a[0]) continue;
for(a[2]=0;a[2]<=50;a[2]++){
if(a[2]==a[0]||a[2]==a[1]) continue;
for(a[3]=0;a[3]<=50;a[3]++){
if(a[3]==a[0]||a[3]==a[1]||a[3]==a[2]) continue;
if(a[0]+a[1]+a[2]+a[3]==116) x++;
}
}
}
}
printf("x=%d\n",x);
printf("x%%4!=%d%%24=%d\n\n",x,x%24);
}

void fun2(){
int a[4]={0};
int y=0;
for(a[0]=0;a[0]<=50;a[0]++){
for(a[1]=a[0]+1;a[1]<=50;a[1]++){
for(a[2]=a[1]+1;a[2]<=50;a[2]++){
for(a[3]=a[2]+1;a[3]<=50;a[3]++){
if(a[0]+a[1]+a[2]+a[3]==116) y++;
}
}
}
}
printf("y=%d\n",y);
printf("y*4!=%d*24=%d\n",y,y*24);
}

int main(){
fun1();
fun2();
return 0;
}

【运行结果】
x=70272
x%4!=70272%24=0

y=2928
y*4!=2928*24=70272
Press any key to continue

【说明】
可以看到问题是出现在了相等的上面……
对于相等的情况
排列组合时会出现重复的答案……
如果能把重复的答案数目计算出来就好了……
linren 2009-09-14
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ark_xu 的回复:]

(3)考虑到a3~a8这6个数都是50,所以还可以强制a8>=a7>=a6>=a5>=a4>=a3 规定了循环上界
假设得到一组解是a1=0,a2=0,a3=5,a4=10,a5=15,a6=20,a7=25,a8=42
那么对a3~a8进行全排列,等于得到了6!种解
当然如果a1=0,a2=0,a3=16,a4=a5=a6=a7=a8=20,有重复的就不是得到6!种解,这个问题自己解决吧
[/Quote]
仔细想了想……
如果用这种办法计算……
得到的数应该是720的倍数
与49892973204这个数有一些出入……

于是就写了下面的程序:

【程序】
#include <stdio.h>

void fun1(){
int a[4]={0};
int x=0;
for(a[0]=0;a[0]<=50;a[0]++){
for(a[1]=0;a[1]<=50;a[1]++){
for(a[2]=0;a[2]<=50;a[2]++){
for(a[3]=0;a[3]<=50;a[3]++){
if(a[0]+a[1]+a[2]+a[3]==116) x++;
}
}
}
}
printf("x=%d\n",x);
printf("x%%4!=%d%%24=%d\n\n",x,x%24);
}

void fun2(){
int a[4]={0};
int y=0;
for(a[0]=0;a[0]<=50;a[0]++){
for(a[1]=a[0];a[1]<=50;a[1]++){
for(a[2]=a[1];a[2]<=50;a[2]++){
for(a[3]=a[2];a[3]<=50;a[3]++){
if(a[0]+a[1]+a[2]+a[3]==116) y++;
}
}
}
}
printf("y=%d\n",y);
printf("y*4!=%d*24=%d\n",y,y*24);

}

int main(){
fun1();
fun2();
return 0;
}

【运行结果】
x=77435
x%4!=77435%24=11

y=3547
y*4!=3547*24=85128
Press any key to continue

【说明】
程序中只使用了4个数
而且是都可以从0~50的数……
不妨可以认为这是限制a1=a2=a3=a4=0时得到解的数目……

用方法(3)计算出的结果85128
用枚举计算出的结果为77435……

可以看到方法(3)计算出的结果比实际的结果要偏大一些……
linren 2009-09-14
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 morilasi 的回复:]
只需要算个数的话DP就足够了。
代码没做优化
C/C++ code#include<iostream>usingnamespace std;#define TARGET 116int arr[8]={50,40,30,50,50,50,50,50};longlong dp[120][8];int
main(void)
{for(int i=0;i<=arr[0];i++)
dp[i][0]=1;for(int i=1;i!=8;i++)
{for(int j=TARGET;j!=-1;j--)
{if(j>arr[i]&&dp[j-arr[i]]==0)break;for(int k=0;k<=arr[i];k++)
{if(k>j)break;
dp[j][i]+=dp[j-k][i-1];
}
}
}
cout<<dp[116][7]<<endl;
}
[/Quote]
这个办法好……

稍微修改了一下……
【程序】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/////////////////////////////////////
#define N 8
int a[N]={50,40,30,50,50,50,50,50};
/////////////////////////////////////

void fun(int n){
int i,j,k;
__int64 *s;

s=(__int64*)malloc(sizeof(__int64)*(n+1)*N);
memset(s,0,sizeof(__int64)*(n+1)*N);
for(i=0;i<=a[0];i++) *(s+i*N)=1;

for(i=1;i<N-1;i++){
for(j=n;j>=0;j--){
for(k=0;k<=a[i];k++){
if(k>j) break;
*(s+N*j+i)=*(s+N*j+i)+*(s+N*(j-k)+i-1);
}
}
}
j=n;
for(k=0;k<=a[i];k++){
if(k>j) break;
*(s+N*j+i)=*(s+N*j+i)+*(s+N*(j-k)+i-1);
}

printf("number:\n%I64d\n",*(s+N*n+N-1));
free(s);
}

int main(void)
{
fun(116);
return 0;
}

【运行结果】
number:
49892973204
Press any key to continue
G_cofa 2009-09-14
  • 打赏
  • 举报
回复
UP!
linren 2009-09-14
  • 打赏
  • 举报
回复
【程序】
#include <stdio.h>
#include <windows.h>
#include <time.h>

int c[2]={0};
int d[2]={0};

void subfun(LPVOID sc){
int a[8]={0};
int b[8]={0};
int i;
for(a[0]=0;a[0]<=50;a[0]=a[0]+2){//a1
printf(" sub thrd [%d/50]\n",a[0]);
b[0]=a[0];
for(a[1]=0;a[1]<=50;a[1]++){//a4
printf(" sub thrd [%d/50]\t[%d/50]\n",a[0],a[1]);
b[1]=b[0]+a[1];
if(b[1]>116) break;
for(a[2]=0;a[2]<=50;a[2]++){//a5
b[2]=b[1]+a[2];
if(b[2]>116) break;
for(a[3]=0;a[3]<=50;a[3]++){//a6
b[3]=b[2]+a[3];
if(b[3]>116) break;
for(a[4]=0;a[4]<=50;a[4]++){//a7
b[4]=b[3]+a[4];
if(b[4]>116) break;
for(a[5]=0;a[5]<=30;a[5]++){//a3
b[5]=b[4]+a[5];
if(b[5]>116) break;
if(b[5]<26) continue;
for(a[6]=0;a[6]<=40;a[6]++){//a2
b[6]=b[5]+a[6];
if(b[6]>116) break;
a[7]=116-b[6];//a8
if(a[7]>50) continue;
if(d[0]==999999999){
for(i=0;i<2;i++) if(d[i]!=999999999) break;
d[i]++;
for(i=i-1;i>=0;i--) d[i]=0;
}else d[0]++;
}
}
}
}
}
}
}
}

int main(){
int a[8]={0};
int b[8]={0};
char s[100];
int x;
int i;
HANDLE thrd;
int t1,t2;

t1=time(NULL);

thrd=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)subfun,NULL,0,NULL);

for(a[0]=1;a[0]<=50;a[0]=a[0]+2){//a1
printf("main thrd [%d/50]\n",a[0]);
b[0]=a[0];
for(a[1]=0;a[1]<=50;a[1]++){//a4
printf("main thrd [%d/50]\t[%d/50]\n",a[0],a[1]);
b[1]=b[0]+a[1];
if(b[1]>116) break;
for(a[2]=0;a[2]<=50;a[2]++){//a5
b[2]=b[1]+a[2];
if(b[2]>116) break;
for(a[3]=0;a[3]<=50;a[3]++){//a6
b[3]=b[2]+a[3];
if(b[3]>116) break;
for(a[4]=0;a[4]<=50;a[4]++){//a7
b[4]=b[3]+a[4];
if(b[4]>116) break;
for(a[5]=0;a[5]<=30;a[5]++){//a3
b[5]=b[4]+a[5];
if(b[5]>116) break;
if(b[5]<26) continue;
for(a[6]=0;a[6]<=40;a[6]++){//a2
b[6]=b[5]+a[6];
if(b[6]>116) break;
a[7]=116-b[6];//a8
if(a[7]>50) continue;
if(c[0]==999999999){
for(i=0;i<2;i++) if(c[i]!=999999999) break;
c[i]++;
for(i=i-1;i>=0;i--) c[i]=0;
}else c[0]++;
}
}
}
}
}
}
}
WaitForSingleObject(thrd,INFINITE);

printf("c: \t");
if(c[1]==0) printf("%d\n",c[0]);
else printf("%d%09d\n",c[1],c[0]);

printf("d: \t");
if(d[1]==0) printf("%d\n",d[0]);
else printf("%d%09d\n",d[1],d[0]);

x=c[0]+d[0];
if(x>999999999){
c[1]=c[1]+d[1]+x/1000000000;
c[0]=c[0]+d[0]+x%1000000000;
}else{
c[1]=c[1]+d[1];
c[0]=c[0]+d[0];
}

t2=time(NULL);

printf("number:\n");
if(c[1]==0) printf("%d\n",c[0]);
else printf("%d%09d\n",c[1],c[0]);
printf("use time: %d:%02d\n",(t2-t1)/60,(t2-t1)%60);

if(c[1]==0) sprintf(s,"number:\n%d\n",c[0]);
else sprintf(s,"%d%09d\n",c[1],c[0]);
sprintf(s,"%suse time: %d:%02d\n",s,(t2-t1)/60,(t2-t1)%60);
MessageBox(NULL,s,"number",0);
return 0;
}

【运行结果】


【说明】
这个是9楼使用的程序……
用时为20分钟15秒……

因为电脑是双核处理器
所以就使用了2个线程来进行计算了……
linren 2009-09-14
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ark_xu 的回复:]
八重循环?你应该想些剪枝

a1=30,a2=40,a3=a4=...=a8=50

(1)一个显然的就是用七重循环 最后a8=116-sum(a[i]) //i=1~7
得到的a8如果在0~50这个范围内就是一个解
(2)每一层循环并不是从0~a[i]都执行的
你可以想一下,假设a1=30,a2=40,a3=47,那么a1+a2+a3=117>116 后面还用执行吗?
同样如果前面几个a[i]都很小,使后面的循环取到最大都达不到116,也不用执行下去了
这样可以减掉一部分
(3)考虑到a3~a8这6个数都是50,所以还可以强制a8>=a7>=a6>=a5>=a4>=a3 规定了循环上界
假设得到一组解是a1=0,a2=0,a3=5,a4=10,a5=15,a6=20,a7=25,a8=42
那么对a3~a8进行全排列,等于得到了6!种解
当然如果a1=0,a2=0,a3=16,a4=a5=a6=a7=a8=20,有重复的就不是得到6!种解,这个问题自己解决吧

把a[i]的值调换了,这不是问题,输出的时候换回来就行

输出方案只能枚举,可是答案本身的规模就太大了,剪枝想不到其他的了,剪也白搭
应该不会有这么要求的题,只能稍微练练脑子
[/Quote]
13楼的办法好……
尤其是(3)的部分……
一下子就把时间缩减至之前的1/720了^_^……



做一个小小的补充……
(4)7重循环的最后两个的下界可以计算出来……

比如说a7……
设:
x=a1+a2+...+a6

如果x<=66
那么a7就可以直接从66-x开始……

设:
y=a1+a2+...+a5

如果y<=16
那么a6就可以直接从16-y开始……
加载更多回复(17)

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧