找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2423|回复: 0

动态规划法解数字加符号的运算结果

[复制链接]
发表于 2014-9-3 00:52:06 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
今天看到有同学华为面试,而我痛苦去不了,在外实习赶不上啊。
看到很多论坛讨论这样一道题:
1,2,3,....9 n个数,每个数字前可以加'+' '-' 或空,要求输出所有满足计算结果为某数的所有表达式

我刚看到这个问题就觉得可以用动态规划做,经过一阵研究得出下面递推式:
F(n,m)=∩F(k-1,m±Interger(a[k,n]))   遍历k∈[0,n-1]  如果不存在k则在数组[0-n]范围内无法找到结果为m的表达式
反之则在n=0时输出。
欢迎大家一起测试。

代码如下:

  1. #include <iostream>
  2. using namespace std;

  3. #define arr(x,y) arr[(x)*size2+(y)]

  4. const int num=9;
  5. int arr[num]={1,2,3,4,5,6,7,8,9};//第一个数之前也可以有符号
  6. char sig[num];

  7. int getmax(int i,int j)
  8. {
  9.         int result=0;
  10.         for(int k=i;k<=j;k++)
  11.                 result=result*10+arr[k];
  12.         return result;
  13. }

  14. bool func(int n,int m)
  15. {//F[n,m]用来求arr[0-n]内运算产生结果m的所有解
  16.         int j;
  17.         //结果
  18.         if(m == 0 || n == 0)
  19.         {
  20.                 if(m == 0)
  21.                 {
  22.                         for(int k=0;k<num;k++)
  23.                         {
  24.                                 cout<<sig[k]<<arr[k];
  25.                         }
  26.                         cout<<endl;
  27.                 }
  28.                 if(n == 0)
  29.                 {
  30.                         if(arr[n] == m)
  31.                         {
  32.                                 sig[0]='+';
  33.                                 for(int k=0;k<num;k++)
  34.                                 {
  35.                                         cout<<sig[k]<<arr[k];
  36.                                 }
  37.                                 cout<<endl;
  38.                                 return true;
  39.                         }
  40.                         else if(arr[n] == -m)
  41.                         {
  42.                                 sig[0]='-';
  43.                                 for(int k=0;k<num;k++)
  44.                                 {
  45.                                         cout<<sig[k]<<arr[k];
  46.                                 }
  47.                                 cout<<endl;
  48.                                 return true;
  49.                         }
  50.                         else
  51.                                 return false;
  52.                 }
  53.                 return true;
  54.         }

  55.         //限界
  56.         if(n < 0)
  57.                 return false;
  58.         int curmax=getmax(0,n);
  59.         if(m > curmax || m < -curmax)
  60.                 return false;
  61.        

  62.         //动态规划F(n,m)=∩F(k-1,m±Interger(a[k,n]))   遍历k∈[0,n-1]
  63.         bool ret=false;
  64.         for(int k=0;k<=n;k++)
  65.         {
  66.                 int max=getmax(k,n);
  67.                 sig[k]='+';
  68.                 for(j=k+1;j<=n;j++)
  69.                         sig[j]='\0';
  70.                 if(func(k-1,m-max))
  71.                 {
  72.                         ret=true;
  73.                 }
  74.                        
  75.                 sig[k]='-';
  76.                 for(j=k+1;j<=n;j++)
  77.                         sig[j]='\0';
  78.                 if(func(k-1,m+max))
  79.                 {

  80.                         ret=true;
  81.                 }
  82.         }

  83.         return ret;
  84. }

  85. void main()
  86. {
  87.         int i,j;
  88.         int object=123;


  89.         func(num-1,object);
  90. }
复制代码


对于n:1-9  m:123,可以得到如下结果:
-1-2 3-4-5+6 7+8 9
-1-2 3+4 5+6+7+8 9
-1+2 3+4-5+6+7+8 9
+1+2 3+4+5-6+7+8 9
+1-2+3+4 5-6-7+8 9
-1-2 3+4+5 6+7 8+9
-1 2-3+4 5+6+7 8+9
-1+2+3 4-5+6+7 8+9
-1-2-3+4 5-6+7 8+9
+1+2+3 4+5-6+7 8+9
-1-2-3+4 5+6 7+8+9
-1-2+3 4+5+6 7+8+9
-1-2-3+4+5 6+7 8-9
+1-2+3-4+5 6+7 8-9
-1-2+3+4 5+6+7 8-9
+1 2+3+4 5-6+7 8-9

m=45时(我以为只有连加呢,,结果结果出了一大堆)
+1-2 3+4 5-6 7+8 9
-1+2 3-4+5-6 7+8 9
+1+2 3+4-5-6 7+8 9
-1-2+3+4-5 6+7+8 9
+1 2-3-4-5 6+7+8 9
-1-2-3-4 5-6+7+8 9
+1 2+3+4-5 6-7+8 9
-1+2 3-4-5 6-7+8 9
+1-2+3-4 5+6-7+8 9
-1-2-3 4+5-6-7+8 9
+1-2 3-4-5-6-7+8 9
-1+2 3+4 5+6 7-8 9
-1-2-3-4 5+6+7 8+9
+1 2-3-4 5-6+7 8+9
+1+2-3 4-5-6+7 8+9
+1+2+3-4 5+6 7+8+9
-1-2-3 4-5+6 7+8+9
+1-2-3 4+5 6+7+8+9
+1+2+3+4+5+6+7+8+9
+1+2 3-4-5+6+7+8+9
-1 2+3 4+5-6+7+8+9
-1-2+3 4-5-6+7+8+9
-1-2+3 4-5+6-7+8+9
+1-2-3+4 5-6-7+8+9
-1+2+3 4+5-6-7+8+9
+1 2+3 4-5-6-7+8+9
-1+2 3-4 5+6 7-8+9
-1-2 3-4+5+6 7-8+9
+1-2 3+4-5+6 7-8+9
-1-2 3+4+5 6+7-8+9
-1 2-3-4+5 6+7-8+9
-1+2 3+4+5+6+7-8+9
-1+2+3 4-5+6+7-8+9
-1+2-3+4 5-6+7-8+9
-1 2+3+4+5 6-7-8+9
-1+2-3-4+5 6-7-8+9
-1-2-3+4 5+6-7-8+9
-1-2+3 4-5 6+7 8-9
+1 2+3-4 5+6+7 8-9
+1-2-3 4+5+6+7 8-9
-1 2+3-4-5-6+7 8-9
+1+2 3-4 5+6 7+8-9
+1-2 3-4+5+6 7+8-9
+1+2 3+4+5+6+7+8-9
-1-2-3+4 5-6+7+8-9
-1-2+3-4+5 6-7+8-9
+1-2+3+4 5+6-7+8-9
-1-2-3-4+5+6 7-8-9
-1-2-3-4-5+6 7-8-9
-1-2-3+4+5 6+7-8-9
-1-2+3-4+5 6+7-8-9
-1+2+3+4 5+6+7-8-9
+1 2-3+4+5 6-7-8-9
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 06:16 , Processed in 0.034507 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表