[BZOJ2239]猜谜语
来源:互联网 发布:angular.js官网 编辑:程序博客网 时间:2024/05/06 10:53
题目描述给出一个长度为N的数字字符串和一个数字T,要求插入最少的加号或者乘号,使得数字字符串的运算结果为T。运算符*号优先级高于+号,运算数可以有任意个前导0.输入输入不超过5组数据,每组数据两行。每组数据的第一行为长度N,只包含0~9的数字字符串;第二行为一个数字T。输入T<0表示输入结束。输出输出一个数字单独占一行,表示最少需要添加的运算符(+号或*号)数,无解输出-1.样例输入123123000000000000000000992299400320895333900-1样例输出00532提示对于30%的数据,有1<=N<=10,0<=T<=50.对于50%的数据,有1<=N<=15,0<=T<=200.对于全部的数据,有1<=N<=20,0<=T<=250.题解:分为两步:
第一步处理只有乘号的情况:
dp[i][j][k]: 从第i个数字, 到第j个数字, 运算结果为k时, 所需要添加的最少乘号个数。
dp[i][j][k]=min( dp[i][j][k], dp[i][p][x]+1 ) ( i<=p<j, k整除x且x=k/num[p+1][j] )
num[p+1][j]为从第p+1个数字到第j个数字组成的数的值。
初始值为dp[i][j][num[i][j]]=0
注意num[p+1][j]为0时要特别处理, 因为乘法中乘一个0就是0了
第二步处理有乘号和加号的情况:
G[i][j]: 前i个字符, 运算结果为j时, 需要添加的最少的运算符个数。
G[i][j]=min( G[i][j], G[k][j-x]+dp[k+1][i][x]+1 ) ( 0<=k<i, 0<=x<=j )
初始值G[i][j]=dp[0][i][j]#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int N=25; const int M=255; int n, T, num[N][N]; char s[N]; int dp[N][N][M], G[N][M]; int main() { for(;;) { scanf( "%s%d", s+1, &T ); if( T<0 ) break; memset( num, -1, sizeof num ); memset( dp, 0x3f, sizeof dp ); memset( G, 0x3f, sizeof G ); G[0][0]=0; n=strlen( s+1 ); for( int i=1; i<=n; i++) for( int j=i; j<=n; j++ ){ int tmp=0; for( int k = i; k<=j; k++ ) tmp=tmp*10+s[k]-'0'; num[i][j]=tmp; if( 0<=tmp && tmp<=T) dp[i][j][tmp]=0; } for( int i=1; i<=n; i++ ) for( int j=i; j<=n; j++ ) for( int p=i; p<j; p++ ) { if( !num[p+1][j] ) dp[i][j][0]=min( dp[i][j][0], 1 ); dp[i][j][0]=min( dp[i][j][0], dp[i][p][0]+1 ); for( int k=1; k<=T; k++ ) if( num[p+1][j]>0 && !( k%num[p+1][j] ) ) dp[i][j][k]=min( dp[i][j][k], dp[i][p][ k/num[p+1][j] ]+1 ); } for( int i=1; i<=n; i++ ) for( int j=0; j<=T; j++ ) for( int k=0; k<i; k++ ) for( int x=0; x<=j; x++ ) G[i][j]=min( G[i][j], G[k][x]+dp[k+1][i][j-x]+1 ); if( G[n][T]>=INF ) printf( "-1\n" ); else printf( "%d\n", G[n][T]-1 ); } return 0; }
阅读全文
0 0
- [BZOJ2239]猜谜语
- [BZOJ2239]猜谜语
- #bzoj2239#猜谜语(DP)
- 【BZOJ2239】【C++心路历程38】猜谜语【dp线型序列分组计算】
- [bzoj2239] 猜谜 迭代深搜 or 动态规划
- 猜谜语
- 猜谜语
- 猜谜语
- 猜谜~
- 猜谜
- 猜谜语(转的)
- 课堂练习js猜谜语
- 破解,就是个猜谜语的游戏
- 猜谜会错意
- 动画片猜谜
- 请猜谜 * 请猜谜 = 请边赏灯边猜
- 汽车灯语大猜谜
- 面试二代:二逼大猜谜
- antd源码解析(一)button控件的解析
- js定时动态增加列表
- BigDecimal加减乘除运算
- 自定义view实现多点触控
- mybatis常用jdbcType数据类型以及对应的JavaType
- [BZOJ2239]猜谜语
- lwip下TCP客户端的实现
- LeetCode#117. Populating Next Right Pointers in Each Node II
- hadoop1.x的单机与伪分布式部署
- yum红帽6.4替换成centos
- 2017前端面试题珍藏
- [LeetCode]500. Keyboard Row
- 跟踪pmon
- POJ