dp转图论——cf1070A好题
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp转图论——cf1070A好题相关的知识,希望对你有一定的参考价值。
dp的状态转移很像一张有向图:每个状态为一个点,每中转移方案是一条有向边
本题要求是求出最小的数,那我们用状态[i,j]表示模i,数位和为j,那么从每个点出发的十条有向边代表[0,9]十个数
从每个状态点进行bfs,由于队首的点必定是当前最小的(因为bfs的顺序),所以可以保证最后求出的是最小的数
/* dp[i][j]表示余数为i,和为j的状态是否被访问到 用pre[i,j,k]表示状态[i,j]是从k转移得到的 等效于一张有d*s个结点的图,要从(0,0)走到(0,s) ,要走最靠左边的路 */ #include<bits/stdc++.h> #include<queue> using namespace std; int d,s,dp[505][5005]; struct Node{ int x,y,z; Node(){} Node(int x,int y,int z):x(x),y(y),z(z){} }pre[505][5005]; void print(int t1,int t2){ if(t1 || t2){ print(pre[t1][t2].x,pre[t1][t2].y); cout<<pre[t1][t2].z; } } queue<pair<int,int> >q; int main(){ cin>>d>>s; q.push(make_pair(0,0)); dp[0][0]=1; while(!q.empty()){ pair<int,int>p=q.front();q.pop(); for(int i=0;i<=9;i++){ int t1=(p.first*10+i)%d; int t2=(p.second+i); if(dp[t1][t2])continue; if(t2>s)break; q.push(make_pair(t1,t2)); dp[t1][t2]=1; pre[t1][t2]=Node(p.first,p.second,i); } } if(dp[0][s]==0){ puts("-1"); return 0; } else { print(0,s); } }
以上是关于dp转图论——cf1070A好题的主要内容,如果未能解决你的问题,请参考以下文章