Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS
題目鏈接:https://codeforces.com/contest/1105
?
C. Ayoub and Lost Array
題目大意:一個長度為n的數組,數組的元素都在[L,R]之間,并且數組全部元素的和可以被3整除,問有多少種方法構建出該數組。答案模1000000007
例
輸入 2 1 3 輸出 3note:滿足的情況只有[1,2],[2,1],[3,3]
解題思路:用dp[i][j]表示長度為i的數組,元素大小在[L,R]之間,并且元素和模3的余數為j的方案數,我們可以計算出[L,R]范圍內模3余0\1\2的數的個數,分別設為num0,num1,num2,?我們可以很容易知道dp[1][0]=num0,dp[1][1]=num1,dp[1][2]=num2,而dp[2][0]需要分情況,當前1個數和模3余0時,第2個數便只能放模3余0的數,即有dp[1][0]*num0種;當前1個數和模3余1時,第2個數便只能放模3余2的數,即有dp[1][1]*num2種;當前1個數和模3余2時,第2個數便只能放模3余1的數,即有dp[1][2]*num1種。dp[n][0]即為我們要求的答案。
于是我們便可以得出遞推式:
dp[i][0]=((dp[i-1][0]*num0%mod+dp[i-1][1]*num2%mod)%mod+dp[i-1][2]*num1%mod)%mod;
dp[i][1]=((dp[i-1][0]*num1%mod+dp[i-1][1]*num0%mod)%mod+dp[i-1][2]*num2%mod)%mod;
dp[i][2]=((dp[i-1][0]*num2%mod+dp[i-1][1]*num1%mod)%mod+dp[i-1][2]*num0%mod)%mod;
代碼:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<set> #include<cmath> #include<list> #include<deque> #include<cstdlib> #include<bitset> #include<stack> #include<map> #include<queue> using namespace std; typedef long long ll; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1] const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-6; const ll mod=1e9+7; const int maxn=100005; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll dp[2000005][5]; ll n,l,r; int main() {ios::sync_with_stdio(false); cin.tie(0);cin>>n>>l>>r;ll num0=r/3-(l-1)/3;ll num1=num0;ll num2=num0;int i,j;for(i=l;i<=r;i++){if(i%3==0)break;else if(i%3==1)num1++;else num2++;}for(j=r;j>=i;j--){if(j%3==2)break;else if(j%3==1){num2--; break;}else if(j%3==0){num1--; num2--;break;}}dp[1][0]=num0; dp[1][1]=num1; dp[1][2]=num2;for(int i=2;i<=n;i++){dp[i][0]=((dp[i-1][0]*num0%mod+dp[i-1][1]*num2%mod)%mod+dp[i-1][2]*num1%mod)%mod;dp[i][1]=((dp[i-1][0]*num1%mod+dp[i-1][1]*num0%mod)%mod+dp[i-1][2]*num2%mod)%mod;dp[i][2]=((dp[i-1][0]*num2%mod+dp[i-1][1]*num1%mod)%mod+dp[i-1][2]*num0%mod)%mod;}cout<<dp[n][0]<<endl;return 0; }?
?
?
D. Kilani and the Game
?
題目大意:給出一個n*m的地圖,最多9個人,每個人至少含有一個城堡,同時有每個人的擴張速度,即可以連續擴張的次數,現在從1-n輪流從各自的城堡開始擴張,不可通過障礙,求整個地圖被擴張完成后,各個人所占領城堡的數目。
Examples
input
3 3 2
1 1
1..
...
..2
output
6 3
解題思路:開始就是想bfs嵌套,先把每一個玩家從1-n的城堡壓入第一個隊列,再每次把第一個隊列的第一個元素彈出,壓入第二個隊列繼續進行bfs,,一直不知道哪里錯了,看了別人博客后才發現那樣是錯的,如果那樣做的話,對于這個樣例是過不了的:
4 3 22 1
1..
1..
..2
... 如果那樣做可能會輸出9 3,而正確答案是10 2。 正確做法應該是每次將第一個隊列相同編號的城堡壓入到第二個隊列,然后再對第二個隊列進行bfs,這樣就不會出現上面那種情況了 代碼: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<set> #include<cmath> #include<list> #include<deque> #include<cstdlib> #include<bitset> #include<stack> #include<map> #include<queue> using namespace std; typedef long long ll; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1] const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-6; const ll mod=1e9+7; const int maxn=100005; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; struct node{int x,y,id;node(int a,int b,int c):x(a),y(b),id(c){} }; struct node1{int x,y,id,steps;node1(int a,int b,int c,int d):x(a),y(b),id(c),steps(d){} }; int n,m,sump,s[10]; vector<node> p[10]; char mp[1050][1050]; queue<node> que; queue<node1> que1; void BFS() {while(que.size()){node tmp=que.front();int id=tmp.id;que1.push(node1(tmp.x,tmp.y,tmp.id,0));while(que.size()&&que.front().id==id) //判斷第一個隊列元素是否為當前壓入隊列是同一個玩家 {que1.push(node1(que.front().x,que.front().y,que.front().id,0));que.pop();}while(que1.size()){node1 now=que1.front();que1.pop();if(now.steps==s[now.id]){que.push(node(now.x,now.y,now.id)); //走到最后一步繼續壓入第一個隊列continue;}for(int i=0;i<4;i++){int dx=now.x+dir[i][0];int dy=now.y+dir[i][1];if(dx>=0&&dx<n&&dy>=0&&dy<m&&mp[dx][dy]=='.'){mp[dx][dy]='0'+now.id;que1.push(node1(dx,dy,now.id,now.steps+1));}}}} } int main() {ios::sync_with_stdio(false); cin.tie(0);cin>>n>>m>>sump;for(int i=1;i<=sump;i++) cin>>s[i];for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>mp[i][j];if(mp[i][j]>='0'&&mp[i][j]<='9')p[mp[i][j]-'0'].push_back(node(i,j,mp[i][j]-'0')); //同一個玩家的城堡壓入同一個向量里 }}for(int i=1;i<=sump;i++)for(int j=0;j<p[i].size();j++)que.push(p[i][j]);BFS();int ans[10];memset(ans,0,sizeof(ans));for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=1;k<=sump;k++)if(mp[i][j]==(k+'0'))ans[k]++;cout<<ans[1];for(int i=2;i<=sump;i++)cout<<" "<<ans[i];cout<<endl;return 0; }
?
轉載于:https://www.cnblogs.com/zjl192628928/p/10303329.html
總結
以上是生活随笔為你收集整理的Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux查看JDK版本和安装位置
- 下一篇: 超市库存管理java sql_超市仓库管