UVa 10306. e-Coins

来源:互联网 发布:典藏邮票网络 编辑:程序博客网 时间:2024/05/17 07:56

题意为有m个向量,将任意个向量相加使得距离刚好为s,求向量的最小个数。

看题后的第一想法是用广搜+dp,后来提交代码却RE了(应该不会的)。后来用枚举试了一下,还是RE。所以才想到是不是数组开小了一点,于是将数组开大了一点,结果果然AC了。其实广搜+dp应该更快的,而且空间复杂度也较小。

 

广搜+dp:

#include <iostream>#include <cstdio>#include <string.h>#include <cmath>#include <queue>using namespace std;struct node{int x,y;}vec[50];int dp[310][310];int m,s;void bfs(){node n0;n0.x =0; n0.y =0;dp[0][0]= 0;queue<node> que;que.push( n0);int flag= 0;while( !que.empty() ){node tem =que.front();que.pop();int xxx=tem.x*tem.x +tem.y* tem.y;if( xxx ==s*s){printf("%d\n", dp[tem.x][tem.y]);flag=1;break;}if( xxx>s*s ){continue;}int i;for( i=0; i<m; i++){node no;no.x =tem.x+ vec[i].x;no.y =tem.y+ vec[i].y; if(!dp[no.x][no.y] ||dp[tem.x][tem.y]+1< dp[no.x][no.y] ){dp[no.x][no.y] =dp[tem.x][tem.y]+1;que.push( no);}}}if( !flag)printf("not possible\n");}int main(){int t;scanf("%d", &t);while( t--){scanf("%d%d", &m, &s);int i;for( i=0; i<m; i++)scanf("%d%d", &vec[i].x, &vec[i].y );memset( dp, 0, sizeof( dp));bfs();}return 0;}