题意:给你一个计算器,对一个数字X进行操作得到另一个数字Y,有以下的操作
1:X*10+i
2:X+i
3:X*i
每个操作数字i都有一个对应的权值,问最少需要花费多少?
题解:很容易能想到广搜,对所有的状态进行枚举,如果当前的状态相比之前的花费更小,那么就将这个状态进行入队扩展,明显数字是不能减小的,如果得到的状态大于终点状态,那么就忽略
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cstring> #include<utility> using namespace std; #define N 20 int cost[N][N]; int vis[100005]; #define inf 0x3f3f3f3f int anscost, ansstep; struct point { int cst, stu, step; point(int _cst, int _stu, int _step) :cst(_cst), stu(_stu), step(_step){} point(){} }; void bfs(int st, int ed) { queue<point>q; q.push(point(0, st, 0)); vis[st] = 0; point top, tmp; while (!q.empty()) { top = q.front(); q.pop(); for (int i = 0; i<3; i++) { for (int j = 0; j<10; j++) { int x, y, z; x = top.cst; y = top.stu; z = top.step; if (i == 0) { y = y * 10 + j; } else if (i == 1) { y += j; } else { y *= j; } x += cost[i][j]; z += 1; if (y>ed) continue; if (x<vis[y]) { //printf("cost:%d stastu:%d step:%d\n", x, y, z); vis[y] = x; q.push(point(x, y, z)); if (y == ed&&anscost>x) { anscost = x; ansstep = z; } } } } } return; } int main() { #ifdef CDZSC freopen("i.txt","r",stdin); //freopen("o.txt", "w", stdout); #endif int x, y,cas=0; while (~scanf("%d%d", &x, &y)) { anscost = inf, ansstep = inf; memset(vis, inf, sizeof(vis)); for (int i = 0; i<3; i++) { for (int j = 0; j<10; j++) { scanf("%d", &cost[i][j]); } } bfs(x, y); printf("Case %d: %d %d\n",++cas,anscost, ansstep); } return 0; }