加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

sgu - 269 - Rooks(大数dp)

发布时间:2020-12-14 04:03:10 所属栏目:大数据 来源:网络整理
导读:题意:给出一个n行的棋盘,每行的长度任意,问在该棋盘中放k个车(不能同行或者同列)有多少种放法(n = 250,每行的长度 = 250)。 题目链接:http://acm.sgu.ru/problem.php?contest=0problem=269 ——开始的时候冒险用dfs去做,结果TLE了。。。改dp,大数长

题意:给出一个n行的棋盘,每行的长度任意,问在该棋盘中放k个车(不能同行或者同列)有多少种放法(n <= 250,每行的长度 <= 250)。

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=269

——>>开始的时候冒险用dfs去做,结果TLE了。。。改dp,大数长度开小点WA,开大点MLE……最后改用滚动数组开1000位的大数长度才A掉……

设d[i][j]表示前i行放j个车的方法数,

则状态转移方程为:d[i][j] = d[i-1][j] + d[i-1][j-1] * (b[i] - j + 1);

改滚动数组:d[j] = d[j] + d[j-1] * (b[i] - j + 1);

#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 250 + 2;
const int maxl = 1000;
int b[maxn];

struct bign{
    int len,s[maxl];
    bign(){
        memset(s,sizeof(s));
        len = 1;
    }
    bign operator = (int num){
        len = 0;
        while(num > 0){
            s[len++] = num % 10;
            num /= 10;
        }
        if(!len){
            s[0] = 0;
            len = 1;
        }
        return *this;
    }
    bign(int num){
        *this = num;
    }
    bign operator + (const bign& b) const{
        bign c;
        c.len = 0;
        for(int i = 0,g = 0; g || i < max(len,b.len); i++){
            int x = g;
            if(i < len) x += s[i];
            if(i < b.len) x += b.s[i];
            c.s[c.len++] = x % 10;
            g = x / 10;
        }
        return c;
    }
    bign operator * (const bign& b) const
    {
        bign c;
        c.len = len + b.len;
        for(int i = 0; i < len; i++)
            for(int j = 0; j < b.len; j++)
                c.s[i+j] = c.s[i+j] + s[i] * b.s[j];
        for(int i = 0; i < c.len-1; i++)
        {
            c.s[i+1] = c.s[i+1] + c.s[i] / 10;
            c.s[i] = c.s[i] % 10;
        }
        while(c.len > 1 && !c.s[c.len-1]) c.len--;
        return c;
    }
    void print(){
        for(int i = len - 1; i >= 0; i--) printf("%d",s[i]);
        printf("n");
    }
}d[maxn];

int main()
{
    int n,k,i,j;
    while(scanf("%d%d",&n,&k) == 2){
        for(i = 1; i <= n; i++) scanf("%d",&b[i]);
        sort(b+1,b+1+n);
        memset(d,sizeof(d));
        d[0] = 1;
        for(i = 1; i <= n; i++){
            for(j = k; j >= 1; j--){
                d[j] = d[j] + d[j-1] * (b[i] - j + 1);
            }
        }
        d[k].print();
    }
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读