塗抹果醬
tyvj兩周年慶典要到了,sam想為tyvj做乙個大蛋糕。蛋糕俯檢視是乙個n×m的矩形,它被劃分成n×m個邊長為1×1的小正方形區域(可以把蛋糕當成n行m列的矩陣)。蛋糕很快做好了,但光禿禿的蛋糕肯定不好看!所以,sam要在蛋糕的上表面塗抹果醬。果醬有三種,分別是紅果醬、綠果醬、藍果醬,三種果醬的編號分別為1,2,3。為了保證蛋糕的視覺效果,admin下達了死命令:相鄰的區域嚴禁使用同種果醬。但sam在接到這條命令之前,已經塗好了蛋糕第k行的果醬,且無法修改。
現在sam想知道:能令admin滿意的塗果醬方案有多少種。請輸出方案數mod10^6。若不存在滿足條件的方案,請輸出0。
輸入共三行。第一行:n,m;
第二行:k;
第三行:m個整數,表示第k行的方案。
字母的詳細含義見題目描述,其他參見樣例。
輸出僅一行,為可行的方案總數。示例1
對於30%的資料,1≤n×m≤20;對於60%的資料,1≤n≤1000,1≤m≤3;
對於100%的資料,1≤n≤10000,1≤m≤5。
題目思路:
因為有三種果醬,所以考慮三進製狀壓dp,首先初始化三進製的合法狀態(相鄰的不能一樣),用乙個vector儲存
f[i][j]表示第i行狀態為[v[j]]時前i行的方案數,judge用來判斷上下兩行是否合法,index代表第k行狀態在vector中的下標。
因為第k行已經固定,所以要分為兩個階段,第一階段為k行以上的方案數,第二階段為k行以下的方案數,注意第一階段結束後f[k][index]要重新歸1。
最後的答案就是兩個階段相乘的方案數取模
**如下:
#include#define ll long long#define mod 1000000
using
namespace
std;
ll n,m,k,a[
6],f[10010][100
],mode,ans1,ans2;
vector
v;void init(int x,int y)//
初始化合法狀態
else
if(x==0
)
if((int)(y/pow(3,x-1))%3==0
) init(x+1,y+1*pow(3,x)),init(x+1,y+2*pow(3
,x));
else
if((int)(y/pow(3,x-1))%3==1
) init(x+1,y+0*pow(3,x)),init(x+1,y+2*pow(3
,x));
else
init(x+1,y+0*pow(3,x)),init(x+1,y+1*pow(3
,x));
}bool judge(int x,int y)//
判斷x狀態和y狀態分別為上下兩行時是否合法
return
true;}
intmain()
init(
0,0);
int index = find(v.begin(),v.end(),mode)-v.begin();
if(index==v.size())//
如果第k行的狀態不合法
if(k==1)//
如果k為1,那麼第一階段方案數為1
if(k!=1
)
for(int i = 2;i<=n;i++)
}ans1 = f[i][index]%mod;
f[i][index] = 1
;
continue
; }
for(int j = 0;j)}}
}for(int j = 0;j)
ans2 = (ans2+f[n][j])%mod;
cout
<
return0;
}
如果有錯誤的地方,還請各位大佬指正。
塗抹果醬 狀壓dp
題目描述 tyvj 兩周年慶典要到了,sam 想為 tyvj 做乙個大蛋糕。蛋糕俯檢視是乙個n m 的矩形,它被劃分成n m 個邊長為 1 1的小正方形區域 可以把蛋糕當成n 行 m列的矩陣 蛋糕很快做好了,但光禿禿的蛋糕肯定不好看!所以,sam 要在蛋糕的上表面塗抹果醬。果醬有三種,分別是紅果醬 ...
LOJ 10172 塗抹果醬 狀壓DP
題目描述 看完題目,很清楚的想到這道題用狀壓dp來做,只不過這道題是個三進製的,做題過程中須注意轉換。下面簡單說一下演算法 1.用0 1 2 來代替題目中的1 2 3這樣比較方便,將第k行以三進製數存入。先用乙個陣列存所以可行的狀態,若第k行的狀態不在陣列裡,直接輸出0.2.這道題中已經給出了一行的...
DP 塗抹果醬
紀念第乙個純自己寫的狀壓dp 感謝我的好友吳穎涵幫助除錯 流下了沒有技術的淚水 卡點 1.函式see1 see2中的for不能用while 關於0的處理 2.統計答案的迴圈意義review 3.萬年不變陣列範圍 首先陣列意義開範圍 include include include include in...