题意为有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;
}