lintcode 染色问题

lintcode 染色问题

描述

有一个圆形,分成n个扇形,用m种颜色给每个扇形染色,相邻扇形颜色不能相同。求方案总数。

不考虑对称性。
由于这个数可能很大,因此只需返回方案数模1e9 + 7。
1≤n≤1051  1≤n≤10​^5​​
1≤m≤1051 1≤m≤10​5​^5

样例

给定n = 2,m = 3,返回6。

解释:
一个圆划分为 2 个扇形,用 3 种颜色上色方案有“黑红,黑白,白红,白黑,红白,红黑”6 种。

给定 n = 3,m = 2,返回 0。

解释:
一个圆划分为 3 个扇形,用 2 种颜色上色,无论怎么上色,都没法保证相邻的颜色不同。

思路

使用动态规划,考虑每多1块扇形可能的情况:

  1. 多的这一块扇形两边的颜色不一样
    如此,多的这一块有m-2种填法,剩下的n-1块的填法是f(n-1)。一共是f(n-1) * (m-2)
  2. 多的这一块两边的扇形颜色一样
    多的这一块有m-1种,剩下的图形是f(n-2)

两者相加就可以得到递推式:
f(n) = (m-1)f(n-2) + (m-2)f(n-1)

class Solution {
public:
    /**
     * @param n: the number of sectors
     * @param m: the number of colors
     * @return: The total number of plans.
     */
    int getCount(int n, int m) {
        // Write your code here
        vector<unsigned long long> dp(n+2, 0);
        unsigned long long mod = 1e9+7;
        dp[0] = 0;
        dp[1] = m;
        dp[2] = (unsigned long long)m*(m-1) % mod;
        dp[3] = (unsigned long long)m*(m-1)*(m-2) % mod;
        for (int i = 4; i < n+1; i++)
            dp[i] = ((m-2)*dp[i-1] + (m-1)*dp[i-2]) % mod;
        return dp[n];
    }
};

这里要注意的是,dp[2] = (unsigned long long)m*(m-1) % mod;
dp[3] = (unsigned long long)m*(m-1)*(m-2) % mod;这两行,一开始的时候我没有加上强制类型转换 (unsigned long long)得出的结果一直是错的,加上之后就正确了。我猜想是因为m的类型是int,运算完m*(m-1)*(m-2)之后很有可能溢出了。所以我对这个操作进行了测试。

  int int_m = 1999;
  
  unsigned long long ull_m = 1999;
  
  cout << "int: " << int_m * int_m * int_m << endl;

  cout << "int(unsigned long long): " << 
  	(unsigned long long)int_m * int_m * int_m << endl;
  
  cout << "unsigned long long: "<< ull_m * ull_m * ull_m << endl;

第一行输出为 -601928593
第二行输出为 7988005999
第三行输出为 7988005999
结果显而易见了。在运算的时候,遇到大数,一定要注意精度的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值