Chinaunix首页 | 论坛 | 博客
  • 博客访问: 64516
  • 博文数量: 115
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-08 19:09
文章分类
文章存档

2015年(115)

我的朋友

分类: C/C++

2015-08-06 16:50:23

有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
例如:   
var a=[100,99,98,1,2, 3];
var b=[1, 2, 3, 4,5,40];

这个题目的原型是之前做过的ACM动态规划
多米诺骨牌(DOMINO)
问题描述:有一种多米诺骨牌是平面的,其正面被分成上下两部分,每一部分的表面或者为空,或者被标上1至6个点。现有一行排列在桌面上:
顶行骨牌的点数之和为6+1+1+1=9;底行骨牌点数之和为1+5+3+2=11。顶行和底行的差值是2。这个差值是两行点数之和的差的绝对值。每个多米诺骨牌都可以上下倒置转换,即上部变为下部,下部变为上部。
现在的任务是,以最少的翻转次数,使得顶行和底行之间的差值最小。对于上面这个例子,我们只需翻转最后一个骨牌,就可以使得顶行和底行的差值为0,所以例子的答案为1。


这里改变下输入, a中的第i个元素和b中的第i个元素,构成第i组,所以输入为一个二维数组input[][2]
int input[][2] = { {100,1}, {99 ,2 } , {88, 3}, {1,4}, {2,5}, {3,40}};

可以使用一个二维数组,x为当前的组序号,y为这组能达到的差的值,其值为反转的次数。
那么可以预见,这是个稀疏矩阵,为了节省空间,采取三元组来存储。
使用三元组记录结果
typedef struct tagLoc{
int x, y;
char rev;
} Loc;
x记录到目前的处理的组的序号。
y记录计算出的上下两组之间的差。
rev记录要达到这组值翻转的次数。

声明一个大数组Loc all[1000],记录所有的可能性。
当x=0时,
如果不翻转0组,那么有y = 99, rev = 0
如果翻转0组,那么有y=-99, rev =1。

当x=n的时候,
遍历数组all中x=n-1的元素,即上一组的所有可能的值。
对于每个可能值 all[m] (all[m].x = n-1)
如果不翻转n组,那么有 x = n, y = all[m].y +  (input[i][0]-input[i][1]) , rev = all[m].rev
如果翻转第n组,那么有 x = n, y = all[m].y -  (input[i][0]-input[i][1]) , rev = all[m].rev+1

完成所有组后,对于最后一组x= 6,
all中的元素,当x=6时,y的绝对值最小的时候即经过rev次反转上下两组的最小差


点击(此处)折叠或打开

  1. /*
  2.  * =====================================================================================
  3.  *
  4.  * Filename: domino.c
  5.  *
  6.  * Description: DP domino
  7.  *
  8.  * Version: 1.0
  9.  * Created: 10/02/2012 06:16:15 PM
  10.  * Revision: none
  11.  * Compiler: gcc
  12.  *
  13.  * Author: YOUR NAME (),
  14.  * Organization:
  15.  *
  16.  * =====================================================================================
  17.  */
  18. #include <stdlib.h>

  19. #include <stdio.h>

  20. #define MAX (1<<32)-1;


  21. int revcount;
  22. int mindis;


  23. typedef struct tagLoc{
  24.     int x, y;
  25.     char rev;
  26. } Loc;
  27. int LocSize = 0;
  28. Loc* all;

  29. int input[][2] = { {100,1}, {99 ,2 } , {88, 3}, {1,4}, {2,5}, {3,40}};
  30. void domino(){
  31.     int i = 1;
  32.     for(; i< 6; i++){
  33.         revcount = 0;
  34.         mindis = (1<<32)-1;
  35.             
  36.         int steps = input[i][0]-input[i][1];
  37.         int loci = 0;
  38.         int tLocSize = LocSize;
  39.         for(;loci<tLocSize; loci++){
  40.             if(all[loci].x == i-1){
  41.                 int tmpdis;
  42.                 all[LocSize].x = i;
  43.                 all[LocSize].y = all[loci].y+steps;
  44.                 all[LocSize].rev = all[loci].rev;

  45.                 all[LocSize].y > 0? (tmpdis = all[LocSize].y): (tmpdis = 0-all[LocSize].y);
  46.                 if(tmpdis<=mindis){
  47.                     mindis = tmpdis;
  48.                     if(revcount>all[LocSize].rev) revcount = all[LocSize].rev;
  49.                 }
  50.                 LocSize++;

  51.                 all[LocSize].x = i;
  52.                 all[LocSize].y = all[loci].y - steps;
  53.                 all[LocSize].rev = all[loci].rev+1;
  54.                 all[LocSize].y > 0? (tmpdis = all[LocSize].y): (tmpdis = 0-all[LocSize].y);
  55.                 if(tmpdis<mindis){
  56.                     mindis = tmpdis;
  57.                     revcount = all[LocSize].rev;
  58.                 }
  59.                 LocSize++;
  60.             }
  61.         }

  62.     }
  63. }



  64. /*
  65.  * === FUNCTION ======================================================================
  66.  * Name: main
  67.  * Description:
  68.  * =====================================================================================
  69.  */
  70.     int
  71. main ( int argc, char *argv[] )
  72. {

  73.     all = (Loc *)malloc(10000*sizeof(Loc));
  74.     all[0].x = 0;
  75.     all[0].y = 99;
  76.     all[0].rev = 0;
  77.     all[1].x=0;
  78.     all[1].y=-99;
  79.     all[1].rev = 1;
  80.     LocSize= 2;
  81.     domino();
  82.     int i = 0;
  83.     for(;i<LocSize; i++){
  84.         printf ( "%d: x:%d, y %d rev:%d\n",i,all[i].x, all[i].y, all[i].rev );
  85.     }
  86.     printf ( "min distance: %d, reverse time: %d\n",mindis, revcount );
  87.     return EXIT_SUCCESS;
  88. }                /* ---------- end of function main ---------- */


阅读(156) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~