C语言中的砝码称重问题

Python046

C语言中的砝码称重问题,第1张

1、以f(k):几种砝码组合能称出k的重量为状态DP全部n个砝码,然后枚举去掉的m个砝码的组合,对每种组合再DP一次,从f中减掉,剩下的就是能称出的不同重量,复杂度O(n * C(n, m) * m  * max(a))≤38760000。

2、例程:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<memory.h>

/*a数组用于存储从n个整型数

 * 据中取k个数字的数组下标值

 * */

int a[100]={0}

/*data数组用于存储实际的数据,也就是所有砝码的

 * 重量

 * */

 int data[4]={2,2,3,3}

 /*sum数组用于保存再data中取k个树的和,注意

  * 没有唯一化处理,也就是说可能里面存在重复

  * 唯一化处理使用函数unique

  * */

 int sum[100] = {0}

 /*index_sum用于记录sum中最后一个数据的索引值

  * */

 int index_sum = 0

 /*这是一个递归实现,用于获取从[start,length-num]的

  * 某一位数,这个位数对应了data数组的下标,num是从

  * data中取几位数的,fujia是一个附加参数,用于记录当

  * 前获取了几位树,从而方便操作数组a

  * */

void GetNumberNew(int start, int length, int num, int fujia)

/*统计长度为length的sum数组中不重复元素的个数

 * */

int unique(int[], int length)

int main()

{

   //data数组长度

    int length = 4

    

    for(int y = 1 y <= length y++)

    {

        /*从[0,num]中获取y个数*/

        GetNumberNew(0, length, y, y)

    }

   

    printf("%d",unique(sum, index_sum))

   

    return 0

}

void GetNumberNew(int start, int length, int num, int fujia)

{

        for(int i = start i <= length - num i++)

        {

            if (num > 0)

            {

            a[num - 1] = i

            /*从[i+1,length]中获取num-1数

             * */

            GetNumberNew(i +1, length, num-1, fujia)

            }

            else

            {

               for(int x = 0 x < fujia x++)

               {

                    sum[index_sum] += data[a[x]] 

                }

                index_sum++

                return

                }

            }

}

int unique(int sum[], int length)

{

    int temp = index_sum

   // printf("temp:%d ",temp)

        for(int i = 0  i < length - 1 i++)

        {

                for(int j = i + 1 j < length j++)

                {

                        if(sum[i] == sum[j])

                        {

                            /*若有相同的数字则减1,并退出此次循环*/

                            temp--

                            break

                            }

                }

        }

        return temp

}

#include<stdio.h>

struct fama

{

int weightint num

}fama1[10]

int count(struct fama a[10],int k,int n)

{

int temp=0,m=0,p

int w[10000]={0}

for(int i=ki<ni++)

{

for(int j=0j<a[i].numj++)

{

p=1temp+=a[i].weight

for(int x=0x<mx++)

{

if(temp==w[x])

p=0

}

if(p) { w[m]=tempm++}

}

} return m}

void main()

{ int n=0

scanf("%d",&n)

for(int i=0i<ni++)

scanf("%d%d",&fama1[i].weight,&fama1[i].num)

int maxnum=0

for(i=0i<ni++)

maxnum+=count(fama1,i,n)

printf("%d\n",maxnum)

}

给分吧,速度

main( )

{ int n1,n2,n3,n4,n5,n6

int n[5000]={0},i=0,j=0,totle=0,k=0

printf("KechengShi xian guo cheng \n\n")

for(n6=1n6>=-1n6--)

for(n5=1n5>=-1n5--)

for(n4=1n4>=-1n4--)

for(n3=1n3>=-1n3--) /*1代表砝码放在右盘,0代表该砝码没有用到,-1代表砝码放在左盘*/

for(n2=1n2>=-1n2--)

for(n1=1n1>=-1n1--)

{ n[k]=1*n1+2*n2+5*n3+10*n4+20*n5+50*n6

if(n[k]>0)

{ printf(" %d= %d*1+%d*2+%d*5+10*%d+20*%d+50*%d\n",n[k],n1,n2,n3,n4,n5,n6)

i++/*每20种称重方法打印一屏*/

k++

if (i>=20)

{getch()

i=0

clrscr()

printf("zhong liang cheng zhong fang fa\n")

}

}

}

getch()

clrscr()

for(i=0i<ki++)

for(j=i+1j<=kj++) /*消除重复项*/

{ if(n[i]==n[j])

n[j]=0

}

printf("ke yi cheng chu de zhong liang shu wei :\n\n")

for(i=0i<=ki++)

if(n[i]>0)

{

printf("%-5d",n[i]) /*输出称出的重量数和他们总共的个数*/

totle++

}

printf("\n\ngong %d zhong \n",totle)

getch()

}