【八中】快速求和(1143 && [CQOI1143])
来源:互联网 发布:淘宝代购点 编辑:程序博客网 时间:2024/05/01 16:14
声明:快速求和有两道题目,第一题是一般的题目类型,而第二道题目则是数据加强版,数值变大,可能会出现卡死,或时间超限,内存超限的状况,但这在代码中都有优化体现,以达到提升速度,优化程序的目的。
一、快速求和
时间限制: 10 Sec
内存限制: 256 MB
题目描述
给定一个数字字符串,用最少次数的加法让字符串等于一个给定的目标数字。每次加法就是在字符串的某个位置插入一个加号。在需要的所有加号都插入后,就象做普通加法那样来求值。 例如,考虑字符串”12”,做0次加法,我们得到数字12。如果插入1个加号,我们得到3。因此,这个例子中,最少用1次加法就得到数字3。 再举一例,考虑字符串”303”和目标数字6,最佳方法不是”3+0+3”,而是”3+03”。能这样做是因为1个数的前导0不会改变它的大小。 写一个程序来实现这个算法。
输入
第1行:1个字符串S(1<=length(S)<=20)和1个整数N(N<=2^9-1)。S和N用空格分隔。
输出
第1行:1个整数K,表示最少的加法次数让S等于N。如果怎么做都不能让S等于N,则输出-1。
样例输入
2222 8
样例输出
3
提示
二、[CQOI1143]快速求和 数据加强版
时间限制: 1 Sec
内存限制: 128 MB
题目描述
给定一个数字字符串,用最少次数的加法让字符串等于一个给定的目标数字。每次加法就是在字符串的某个位置插入一个加号。在需要的所有加号都插入后,就象做普通加法那样来求值。 例如,考虑字符串”12”,做0次加法,我们得到数字12。如果插入1个加号,我们得到3。因此,这个例子中,最少用1次加法就得到数字3。 再举一例,考虑字符串”303”和目标数字6,最佳方法不是”3+0+3”,而是”3+03”。能这样做是因为1个数的前导0不会改变它的大小。 写一个程序来实现这个算法。
输入
第1行:1个字符串S(1<=length(S)<=40)和1个整数N(N<=10^5)。S和N用空格分隔。
输出
第1行:1个整数K,表示最少的加法次数让S等于N。如果怎么做都不能让S等于N,则输出-1。
样例输入
2222222222222222222222222222222222222222 80
样例输出
39
提示
【代码】解析
无疑,此题可以用三种方法来做:①搜索 ②记忆化搜索 ③DP 在面对超时等情况时,②③种方法都可以使用。用搜索,也就是一个枚举的过程,再用上一个数组,或再减一下枝,这道题就可以顺利的解出来了。详情请见代码。
①DP
正在思考中,闭关修炼。。。char int bool float long double
②搜索+剪枝
#include<cstdio>#include<cstring>#include<algorithm>#include<climits>#include<cmath>using namespace std; char a[225];bool vis[225];int f[225][225],k,lena;int minl=INT_MAX;;#define INTMAX 100000000void dfs(int i,int last,int num,int He)//位置,上个加号,加号数量,和 { if(He+f[last+1][i]>k) return; if(num>=minl) return; //最优性剪枝 if(i==lena) { He+=f[last+1][lena]; if(He==k) if(num<minl) minl=num; return ; } dfs(i+1,last,num,He); int j=f[last+1][i]; dfs(i+1,i,num+1,He+j);}int main(){ scanf("%s",a); scanf("%d",&k); lena=strlen(a); for(int i=0;i<lena;i++) f[i+1][i+1]=a[i]-'0'; for(int i=1;i<lena;i++) for(int j=i+1;j<=lena;j++) { f[i][j]=f[i][j-1]*10+f[j][j]; if(f[i][j]>INTMAX) f[i][j]=INTMAX; } dfs(1,0,0,0); if(minl<lena)printf("%d",minl); else printf("-1");}
③记忆化搜索
#include<cstdio>#include<cstring>#include<algorithm>#include<climits>#include<cmath>using namespace std; char a[45];int f[45][45],memo[45][100005],k,lena;#define INTMAX 100000000int Dp(int i,int goal){ int t,next,minp=INTMAX; if(i>lena) { if(goal==0) return 0; else return INTMAX; } if(memo[i][goal]!=-1) return memo[i][goal]; int &ans=memo[i][goal]; for(int j=i;j<=lena;j++) { t=f[i][j]; if(t>goal) break; next=Dp(j+1,goal-t); if(next<minp) minp=next; } if(minp<INTMAX) ans=minp+1; else ans=INTMAX; return ans;}int main(){ scanf("%s",a); scanf("%d",&k); lena=strlen(a); memset(memo,-1,sizeof(memo)); for(int i=0;i<lena;i++) f[i+1][i+1]=a[i]-'0'; for(int i=1;i<lena;i++) for(int j=i+1;j<=lena;j++) { f[i][j]=f[i][j-1]*10+f[j][j]; if(f[i][j]>INTMAX) f[i][j]=INTMAX; } int tu=Dp(1,k); if(tu==INTMAX)printf("-1"); else printf("%d",tu-1);}
- 【八中】快速求和(1143 && [CQOI1143])
- 1143 快速求和
- 快速求和
- 快速求和
- nyoj420 P次方求和(快速幂)
- [noip模拟赛]求和(快速幂)
- 等比数列求和 (快速幂 + 逆元)
- 快速求和(炒鸡数据版)
- 等比数列求和快速幂
- 排序算法(八):快速排序
- NYOJ 题目420 p次方求和(快速幂)
- nyoj 420 p次方求和 (快速幂)
- HDU1588 Gauss Fibonacci (矩阵快速幂+等比数列二分求和)
- 1097: 树状数组1(快速求和计算)
- 前端面试题(数组中求和)
- BSOJ3299 洛谷P1874 快速求和
- DP——快速求和
- OPENH323中呼叫建立过程的跟踪与分析(八)----非快速隧道方式之被叫端
- Qt struct应用
- 深入理解 Java G1 垃圾收集器
- python2.6.6升级到python2.7.13
- Running the single-view depth demo
- CSS(三十四)
- 【八中】快速求和(1143 && [CQOI1143])
- PHP数据采集常用的方法
- Qt 持久性序列化
- 使用方法与键盘输入计算5的阶乘
- CSS(三十五)
- Centos7开启FTP服务
- CSS3(一)
- 用C/C++实现的结构化数据处理 二进制文件
- 用类描述计算机中的CPU的速度和磁盘的容量