您的位置:首页 > 其它

Interesting Calculator (最短路,广搜+优先队列,dp)(简单题)

2017-04-05 16:50 399 查看
There is an interesting calculator. It has 3 rows of buttons. Row 1: button 0, 1, 2, 3, ..., 9. Pressing each button appends tha4000t digit to the end of the display.Row 2: button +0, +1, +2, +3, ..., +9. Pressing each button adds that digit to the display.Row 3: button *0, *1, *2, *3, ..., *9. Pressing each button multiplies that digit to the display. Note that it never displays leading zeros, so if the current display is 0, pressing 5 makes it 5 instead of 05. If the current display is 12, you can press button 3, +5, *2 to get 256. Similarly, to change the display from 0to 1, you can press 1 or +1 (but not both!). Each button has a positive cost, your task is to change the display from x to y with minimum cost. If there are multiple ways to do so, the number of presses should be minimized.InputThere will be at most 30 test cases. The first line of each test case contains two integers x and y(0<=x<=y<=105). Each of the 3 lines contains 10 positive integers (not greater than 105), i.e. the costsof each button.OutputFor each test case, print the minimal cost and the number of presses.Sample Input
12 2561 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 112 256100 100 100 1 100 100 100 100 100 100100 100 100 100 100 1 100 100 100 100100 100 10 100 100 100 100 100 100 100
Sample Output
Case 1: 2 2Case 2: 12 3
思路:
1.dp的思想,当前状态为最优,最初状态是val
=0;
2.广搜的思想,通过优先队列双for更新val[x]最小值(剪枝)。
3.而这道题该可以被看做是最短路,用spfa进行。基本思路是,1-100000都被当作一个点,
从当前点到下一个点,通过某种或者是某几种运算,记录步数,和相应的花费,
更新节点,得到最小值。
我的失误是,用map容器写成了更新最小值的那个数组,结果是以nlogn的时间复杂度进行访问。
还有其他细节,值得思考。

小启发:原来不止以前的模板题可以用最短路。让我真正理解了。感谢这道题。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<map>#include<stack>#include<queue>#include<vector>using namespace std;typedef long long LL;const int maxn=100050;const int INF=0x3f3f3f3f;int cost[3][10];int dis[maxn],num[maxn];int vis[maxn];int st,ed;int Case=1;void spfa(){memset(dis,INF,sizeof(dis));memset(vis,0,sizeof(vis));queue<int>q;int u,v,t;q.push(st);num[st]=dis[st]=0;while(!q.empty()){u=q.front();q.pop();vis[u]=0;for(int i=0; i<3; i++)for(int j=0; j<10; j++){if(i==0)v=u*10+j;else if(i==1)v=u+j;elsev=u*j;if(v>ed)break;if(dis[v]<=dis[u]+cost[i][j])continue;dis[v]=dis[u]+cost[i][j];num[v]=num[u]+1;if(!vis[v]){vis[v]=1;q.push(v);}}}printf("Case %d: %d %d\n",Case++,dis[ed],num[ed]);}int main(){while(~scanf("%d%d",&st,&ed)){for(int i=0; i<3; i++)for(int j=0; j<10; j++)scanf("%d",&cost[i][j]);spfa();}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: