2021-04-05

Paint Box

https://ac.nowcoder.com/acm/problem/13884

题目描述
我们有n个空盒子,所以让我们用m种颜色重新着色那些盒子。
盒子排成一行。不允许用相同的颜色给任何相邻的盒子上色。框i和框i + 1表示每隔i,1≤i≤n相邻。
我们还希望n个框的不同颜色的总数恰好是k。
当且仅当至少一个盒子用不同颜色上色时,两种方法才被认为是不同的。

对于恰好这个词,在开始还是不太清楚,学习了一段时间之后,对于此有了自己的理解,恰好需要用至少或者不超过来运用容斥原理进行表示。
分析题目..
1.首先需要进行选择颜色种类C(m, k)种选法
2.我们可以假定当前我们有i种颜色可以使用,对当前的j位置进行上***r>图片说明 想一下,我们可以知道对于j位置来说,它只会对旁边两个位置产生影响,所以当前j位置有i种选法,那么其它位置就有i-1种选法,那么就是i(i-1)^(n-1);
3.由题目的描述中的恰好在此题目中,需要理解为不超过k种颜色的容斥原理进行求解。
由上面的三点我们可以得到答案
ans = C(m,k)
(C(k,k)k(k-1)^(n-1) - C(k,k-1)(k-i)(k-2)^(n-1)) + ........
**求解C(m,k),由于m是属于(1,1e9)那么就不能用预处理数组进行求解,可以利用自己喜欢的方式进行求解~~

#include<bits/stdc++.h>
#define ll long long
#define pr printf
#define sc scanf
using namespace std;
const int maxn = 1e6 + 10;

const int mod = 1e9 + 7;
ll fact[maxn],infact[maxn];
ll qpow(ll a, ll b){
    ll ans = 1;
    while(b){
        if(b & 1)ans = ans*a%mod;
        b >>= 1;
        a = a*a%mod;
    }
    return ans;
}
ll inv(ll a){
    return qpow(a,mod-2)%mod;
}
ll C(ll a, ll b){
    if(b > a || a < 0 || b < 0)return 0;
    if(b == 0 || b == a)return 1;
    return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
void init() {
    fact[0] = 1;
    for (int i = 1; i < maxn; i++) {
        fact[i] = fact[i - 1] * i % mod;
    }
    infact[maxn - 1] = qpow(fact[maxn - 1], mod - 2);
    for (int i = maxn - 2; i >= 0; i--) {
        infact[i] = infact[i + 1] * (i + 1) % mod;
    }
}

int main() {
    init();
    int T;
    sc("%d", &T);
    while (T--) {
        ll n, m, k, ans = 0;
        sc("%lld%lld%lld", &n, &m, &k);
        for (int i = 0, cur = 1; i < k; i++, cur = -cur)
            ans = (ans + cur * C(k, k - i) * (k - i) % mod * qpow(k - i - 1, n - 1) % mod + mod) % mod;
        for (int i = 0; i < k; i++)
            ans = ans * (m - i) % mod * inv(k - i) % mod;
        cout << ans << endl;
    }
    return 0;
}
全部评论

相关推荐

会飞的猿:我看你想进大厂,我给你总结一下学习路线吧,java语言方面常规八股要熟,那些java的集合,重点背hashmap八股吧,jvm类加载机制,运行时分区,垃圾回收算法,垃圾回收器CMS、G1这些,各种乐观锁悲观锁,线程安全,threadlocal这些。在进阶一些的比如jvm参数,内存溢出泄漏排查,jvm调优。我这里说的只是冰山一角,详细八股可以去网上找,这不用去买,都免费资源。mysql、redis可以去看小林coding,我看你简历上写了,你一定要熟,什么底层b+树、索引结构、innodb、mvcc、undo log、redo log、行级锁表级锁,这些东西高频出现,如果面试官问我这些我都能笑出来。消息队列rabbitmq也好kafka也好,学一种就行,什么分区啊副本啊确认机制啊怎么保证不重复消费、怎么保证消息不丢失这些基本的一定要会,进阶一点的比如LEO、高水位线、kafka和rocketmq底层零拷贝的区别等等。计算机网络和操作系统既然你是科班应该理解起来问题不大,去看小林coding这两块吧,深度够了。spring boot的八股好好看看吧,一般字节腾讯不这么问,其他的java大厂挺爱问的,什么循环依赖啥的去网上看看。数据结构的话科班应该问题不大,多去力扣集中突击刷题吧。项目的话其实说白了还是结合八股来,想一想你写的这些技术会给你挖什么坑。除此之外,还有场景题、rpc、设计模式、linux命令、ddd等。不会的就别往简历上写了,虽然技术栈很多的话好看些,但背起来确实累。总结一下,多去实习吧,多跳槽,直到跳到一个不错的中厂做跳板,这是一条可行的进大厂的路线。另外,只想找个小厂的工作的话,没必要全都照这些准备,太累了,重点放在框架的使用和一些基础八股吧。大致路线就这样,没啥太多难度,就是量大,你能达到什么高度取决于你对自己多狠,祝好。
点赞 评论 收藏
分享
黑皮白袜臭脚体育生:春节刚过就开卷吗?哈基馆,你这家伙......
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务