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); }
- swjtu oj 1579 加号问题
- swjtu oj 1737
- swjtu oj 1589 Help Alice!
- swjtu-oj 1569 离线并查集
- SWJTU oj Short Problem(异或求和)
- SWJTU oj 2387 Magic Maze(DAG 求最长路)
- SWJTU OJ 西安交通大学第十三届ACM程序设计决赛-题解
- url中加号问题
- php的base64_encode()加号问题
- URL 中“+”加号的问题
- 下载文件名空格变加号问题
- struts2加号在参数中传递问题
- 下载文件时空格变加号问题
- escape函数处理带加号字串问题
- URL传值带加号“+”的问题的解决方法
- JAVA 拼接字符串 加号问题 + StringBuilder/StringBuffer
- escape函数处理带加号字串问题
- url 地址中的+(加号)问题
- android 详细信息显示界面的思路
- 如何写Vim脚本(一)
- 要开始学c语言了
- Linux Sudo的使用
- VB.Net Winform程序的简单打包和部署--<机房收费系统>
- swjtu oj 1579 加号问题
- android开发常用命令
- C语言经典算法:如何较快的分解质因数
- android 2.3 电源管理
- 小心strncpy!
- swjtu oj 1589 Help Alice!
- 非递减顺序表的合并
- ,函数调用问题
- android 2.3 电量管理