热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SRM532第1组第2题:详细解析与优化策略

很有趣的一道题目,套了两个动态规划。PromblemStatement题目大意是有N个顶点,需要连M条无向边,要求两个顶点A,B的序号满足

很有趣的一道题目,套了两个动态规划。

Promblem Statement

题目大意是有N个顶点&#xff0c;需要连M条无向边&#xff0c;要求两个顶点A, B的序号满足0 <|A - B| <&#61; K&#xff0c;K<&#61;8&#xff0c;问说一共有多少种方案。

f[i][j][mask][k]表示考虑顶点0...i&#xff0c;使用j条边&#xff0c;前从i往前的K个顶点加上自己的的位状态是mask&#xff0c;并且考虑从i到i - k的连边方案的总方案数。

则f[N - 1][M][0][K]就是答案。

当顶点i处未连出边&#xff0c;则退化成i-1的情况。

否则考虑从i到i-k的连边&#xff0c;

如果不选择边&#xff0c;且i到i-k的连边继承自从i到i-(k-1)的连边&#xff0c;所以直接传递&#xff1b;

如果选择边&#xff0c;则从边少1条的状态中传递。

#include
using namespace std;

const int MOD &#61; 1000000007;

typedef long long int64;

int64 f[35][1 <<9][35][9];

class DengklekBuildingRoads
{
public:
int numWays(int N, int M, int K)
{
memset(f, 0, sizeof(f));
for(int k &#61; 0; k <&#61; K; k&#43;&#43;)
f[0][0][0][k] &#61; 1;
//f[0][0][0][0] &#61; 1;

for(int i &#61; 1; i {
for(int j &#61; 0; j <&#61; M; j&#43;&#43;)
{
// k &#61; 0
for(int mask &#61; 0; mask <(1 <<(K &#43; 1)); mask&#43;&#43;)
{
if(!(mask & 1)) f[i][mask][j][0] &#61; f[i - 1][mask / 2][j][K];
}
// k > 0
for(int k &#61; 1; k <&#61; K; k&#43;&#43;)
{
for(int mask &#61; 0; mask <(1 <<(K &#43; 1)); mask&#43;&#43;)
{
f[i][mask][j][k] &#61; f[i][mask][j][k - 1];
if(k > i) continue;
f[i][mask][j][k] &#43;&#61; f[i][mask ^ 1 ^ (1 <1][k];
f[i][mask][j][k] %&#61; MOD;
}
}
}
}
return f[N - 1][0][M][K];
}
};



转:https://www.cnblogs.com/litstrong/archive/2012/02/22/2363433.html



推荐阅读
author-avatar
mnuee
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有