A.番号を探す(思考+ DP + BFS)

タイトル

質問の意味:

    dおよびSが与えられ、望ましくはxは、Dのそれぞれの倍数であり、xとsとなるようにxの可能な限り少数のように構築。
     1 D 500 1 S 5000 1≤d≤500,1≤s≤5000

分析:

    Dは、無意識のうちにそれが列挙の倍数であると思うし、その後、それぞれを維持します。しかし、問題はその倍数が非常に大きくなり、何の解決策になるかもしれない列挙するために、倍数と各ビット間の相関関係ではないあります。
    私たちがしなければ、各列挙の数に基づいて、以前のアイデアを使用していますか?すべての番号を列挙する2つの変数を維持する必要性、および各ビットモジュラスです。D sは、大規模な状態のあまり数はありませんので。その係数の数よりも少ないがある場合の数について、それぞれ、その同じのすべてが、この数は必ずしも答えではありません。だから、どのように我々は、列挙、小規模から大規模まで自然に列挙、私は広いを使用して大規模な列挙に小さなが、その後、中央値は、同じ長さを持つ列挙され、その結果、各番号の後に1を追加してみます達成するために検索します。複雑さはすべて最大であるD * sが、状況が出て更新しています。

#include <iostream>
#include <queue>
#include <string>
using namespace std;

typedef long long ll;

struct node{
	int mod;
	int sum;
	string res;
	node(int a,int b,string c)
	{
		mod = a;
		sum = b;
		res = c;
	}
};

int vis[505][5005];

string bfs(int d,int s)
{
	queue<node> q;
	q.push(node(0,0,""));
	vis[0][0] = 1;
	while( !q.empty() )
	{
		node t = q.front();
	//	cout << t.res << '\n';
		q.pop();
		if( t.mod == 0 && t.sum == s ) return t.res;
		for (int i = 0; i <= 9; i++)
		{
			int mod = ( t.mod * 10 + i ) % d;
			int sum = t.sum + i;
			if( sum > s || vis[mod][sum] ) continue;
			string res = t.res;
			char z = i + '0';
			res += z;
			q.push(node(mod,sum,res));
			vis[mod][sum] = 1;
		}
	}
	return "-1";
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int d,s;
	cin >> d >> s;
	cout << bfs(d,s) << '\n';
	return 0;
}

公開された132元の記事 ウォンの賞賛6 ビュー7906

おすすめ

転載: blog.csdn.net/weixin_44316314/article/details/105181588