public class Main {
public static int paintFence(int n, int k) {
final int MOD = 1000000007;
if (n == 0) return 0;
if (n == 1) return k;
if (n == 2) return (k * k) % MOD;
if (n == 3) return (int)(((long)k * k * k) % MOD);
long[] dp1 = new long[n + 1];
long[] dp2 = new long[n + 1];
long[] dp3 = new long[n + 1];
long[] total = new long[n + 1];
dp1[1] = k;
dp2[1] = 0;
dp3[1] = 0;
total[1] = dp1[1];
dp1[2] = (long)k * (k - 1) % MOD;
dp2[2] = k;
dp3[2] = 0;
total[2] = (dp1[2] + dp2[2]) % MOD;
dp1[3] = ((dp1[2] + dp2[2] + dp3[2]) * (k - 1)) % MOD;
dp2[3] = dp1[2];
dp3[3] = dp2[2];
total[3] = (dp1[3] + dp2[3] + dp3[3]) % MOD;
for (int i = 4; i <= n; i++) {
dp1[i] = (total[i - 1] * (k - 1)) % MOD;
dp2[i] = dp1[i - 1];
dp3[i] = dp2[i - 1];
total[i] = (dp1[i] + dp2[i] + dp3[i]) % MOD;
}
return (int) total[n];
}
public static void main
(String[] args
) { int n = 5, k = 2;
System.
out.
println("Total ways to paint the fence: " + paintFence
(n, k
)); }
}
// Time Complexity: O(n)
// Space Complexity: O(n)
cHVibGljIGNsYXNzIE1haW4gewogICAgcHVibGljIHN0YXRpYyBpbnQgcGFpbnRGZW5jZShpbnQgbiwgaW50IGspIHsKICAgICAgICBmaW5hbCBpbnQgTU9EID0gMTAwMDAwMDAwNzsKCiAgICAgICAgaWYgKG4gPT0gMCkgcmV0dXJuIDA7CiAgICAgICAgaWYgKG4gPT0gMSkgcmV0dXJuIGs7CiAgICAgICAgaWYgKG4gPT0gMikgcmV0dXJuIChrICogaykgJSBNT0Q7CiAgICAgICAgaWYgKG4gPT0gMykgcmV0dXJuIChpbnQpKCgobG9uZylrICogayAqIGspICUgTU9EKTsKCiAgICAgICAgbG9uZ1tdIGRwMSA9IG5ldyBsb25nW24gKyAxXTsKICAgICAgICBsb25nW10gZHAyID0gbmV3IGxvbmdbbiArIDFdOwogICAgICAgIGxvbmdbXSBkcDMgPSBuZXcgbG9uZ1tuICsgMV07CiAgICAgICAgbG9uZ1tdIHRvdGFsID0gbmV3IGxvbmdbbiArIDFdOwoKICAgICAgICBkcDFbMV0gPSBrOwogICAgICAgIGRwMlsxXSA9IDA7CiAgICAgICAgZHAzWzFdID0gMDsKICAgICAgICB0b3RhbFsxXSA9IGRwMVsxXTsKCiAgICAgICAgZHAxWzJdID0gKGxvbmcpayAqIChrIC0gMSkgJSBNT0Q7CiAgICAgICAgZHAyWzJdID0gazsKICAgICAgICBkcDNbMl0gPSAwOwogICAgICAgIHRvdGFsWzJdID0gKGRwMVsyXSArIGRwMlsyXSkgJSBNT0Q7CgogICAgICAgIGRwMVszXSA9ICgoZHAxWzJdICsgZHAyWzJdICsgZHAzWzJdKSAqIChrIC0gMSkpICUgTU9EOwogICAgICAgIGRwMlszXSA9IGRwMVsyXTsKICAgICAgICBkcDNbM10gPSBkcDJbMl07CiAgICAgICAgdG90YWxbM10gPSAoZHAxWzNdICsgZHAyWzNdICsgZHAzWzNdKSAlIE1PRDsKCiAgICAgICAgZm9yIChpbnQgaSA9IDQ7IGkgPD0gbjsgaSsrKSB7CiAgICAgICAgICAgIGRwMVtpXSA9ICh0b3RhbFtpIC0gMV0gKiAoayAtIDEpKSAlIE1PRDsKICAgICAgICAgICAgZHAyW2ldID0gZHAxW2kgLSAxXTsKICAgICAgICAgICAgZHAzW2ldID0gZHAyW2kgLSAxXTsKICAgICAgICAgICAgdG90YWxbaV0gPSAoZHAxW2ldICsgZHAyW2ldICsgZHAzW2ldKSAlIE1PRDsKICAgICAgICB9CgogICAgICAgIHJldHVybiAoaW50KSB0b3RhbFtuXTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgaW50IG4gPSA1LCBrID0gMjsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRvdGFsIHdheXMgdG8gcGFpbnQgdGhlIGZlbmNlOiAiICsgcGFpbnRGZW5jZShuLCBrKSk7CiAgICB9Cn0KCi8vIFRpbWUgQ29tcGxleGl0eTogTyhuKQovLyBTcGFjZSBDb21wbGV4aXR5OiBPKG4p