swjtu oj 1579 加号问题

来源:互联网 发布:sql delete加标记 编辑:程序博客网 时间:2024/05/21 07:24

http://acm.swjtu.edu.cn/JudgeOnline/showproblem?problem_id=1579

明显的DP算法。方便起见,定义一个结构体answer。用来储存一个字符串数字,当然拉,也可以不用,看个人喜好。输入字符串s ,加号个数 m,一个answer的二维数组 OPT[ i ][ j ] ,表示: 用 s 的前 i 的 字符,在这i个字符中加入 j 个加号 ,所求的最小得和。

首先,OPT[ 0 ][ i ] = 0. 表示,取a中的 0个字符 ,加入i 个加号,得到的数,自然是0 .

OPT[ i ][ 0 ]=a[ 0....i-1 ] ,表示 ,取a中的前i个字符 ,加入0个加号,很明显,得到的数为

a[0..i-1].

因此,得到以下公式:

OPT[ n ][ m ] = min{

                                  OPT[ n-1 ][m-1 ] + a[ n-1...n-1 ],

                                     OPT[ n-2 ][m-1 ] + a[ n-2...n-1 ],

                                     OPT[ n-3 ][m-1 ] + a[ n-3...n-1 ],

                                   OPT[ n-4 ][m-1 ] + a[ n-4...n-1 ],

                                   ............

                                   ............

                                    OPT[   0 ][ m-1 ]+a[ 0....n-1 ];

                                   }

循环计算OPT[ n ][ m ];

n=strlen(n);

为 OPT [   i ] [ 0 ] , OPT [ 0 ] [ j ] 赋初值(i=0,1,2,...n) (j=0,1,2.....m);

For i 1 to n

For j 1 to m

计算 OPT[ i ][ j ] (按照以上公式)

输出 OPT[ n ][ m ]

算法就这么简单,但是关于实现,首先,必须写一个字符串相加的函数,由于位数的关系,所有加法都必须基于字符串,其次,一个字符串数字比较的函数,不能用strcmp.





  #include <stdio.h>#include <string>typedef struct { char s[202]; }answer;  answer OPT[201][21]; //OPT[i][j],??s????????i????????????j??????????????????????char *plus(char *a , char *b,int p,int i) {  char s[250],sum[250];  int k=0;  for(k=0;p+k<=i;k++)  s[k]=b[p+k];  sum[0]='0';  int la=strlen(a);  int length=la>k?la:k;  int min=la<k?la:k;  int sign=0,m;  length+=1;  for(m=0;m<min;m++){   sum[length-m-1]=a[la-m-1]+s[k-m-1]+sign-'0';   if(sum[length-m-1]>'9') {sum[length-m-1]-=10;sign=1;}  else     sign=0;   }   while(m<la) {sum[length-m-1]=a[la-m-1]+sign;               if(sum[length-m-1]>'9') {sum[length-m-1]-=10;sign=1;}                else     sign=0;m++;}  while(m<k) {sum[length-m-1]=s[k-m-1]+sign;       if(sum[length-m-1]>'9') {sum[length-m-1]-=10;sign=1;}     else     sign=0;m++;}  if(sum[0]=='0'&&sign==1) sum[0]='1';  sum[length]='\0';  if(sum[0]=='0')  return sum+1;  else  return sum;  }void fun(char *s,int m); int aSmaller(char *a,char *b){  int la,lb;  la=strlen(a);  lb=strlen(b);  if(la<lb) return 1;  else  if(la>lb) return 0;   else    {     int i;     for(i=0;i<la;i++)      if(a[i]<b[i]) return 1;      else      if(a[i]>b[i]) return 0; }  return 0;  } char *plus(char *a , char *b,int p,int i);int main()  {   int n;   scanf("%d",&n);    while(n--)     {      char s[201];      int m;   scanf("%s%d",s,&m);    fun(s,m);      }     return 0;   }   void get(char *a,char *s,int i)   {    int j=0;    for(j=0;j<i;j++)    a[j]=s[j];    a[j]='\0';    }  void fun(char *s,int m)  {    int ls=strlen(s);         int j,i;  for(j=0;j<=m;j++)   strcpy(OPT[0][j].s,"0");       for(i=0;i<=ls;i++)     get(OPT[i][0].s,s,i);   strcpy(OPT[0][0].s,"0");   for(i=1;i<=ls;i++)    for(j=1;j<=m;j++)    {      if(j>=i) {strcpy(OPT[i][j].s,OPT[i][j-1].s);continue;}      char min[250]; char sum[250];   strcpy(sum,plus(OPT[i-1][j-1].s,s,i-1,i-1));   strcpy(min,sum);    int p;    for(p=i-2;p>=0;p--)    {         strcpy(sum,plus(OPT[p][j-1].s,s,p+1-1,i-1));     if(aSmaller(sum,min))           strcpy(min,sum);          }     strcpy(OPT[i][j].s,min);   }printf("%s\n",OPT[ls]­.s);    }


原创粉丝点击