light Oj 1172 二维DP+矩阵 UVa中等题
来源:互联网 发布:vc socket异步编程 编辑:程序博客网 时间:2024/06/01 12:54
light Oj 1172 二维DP+矩阵 UVa中等题
分类: light OJ2013-07-17 22:41 30人阅读 评论(0) 收藏 举报
lightOJ 矩阵题列表: http://lightoj.com/volume_problemcategory.php?user_id=8459&category=Matrix%20Exponentiation
花了1天多的时间,终于把lightOJ 矩阵题 切的只剩一题了, 最后一题只有1人AC,我想了不多不少的时间还是没有什么思路,所以先放一放吧。
先想想sorce很小的情况下如何做这题, 然后把sorce加大,套个矩阵就可以了。
因为dp是二维的,放入矩阵时把二维转变成一维。
我向来不喜欢把矩阵写成一个类,绝大部分人写的代码都是很费时间的,虽然看起来很爽很清楚,不过我熟练自己的写法,light oj基本很多矩阵题都是1A的,没有调试多久,时间也比很多人快。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <cmath>
- using namespace std;
- #define LL unsigned int
- const int N = 160;
- int b, s;
- int n, X;
- LL A[N][N], ans[N][N], B[N];
- void mult(LL a[][N], LL b[][N]) { //矩阵乘法a = a*b
- LL c[N][N] = { 0 };
- int i, j, k;
- for (k = 0; k < n; k++)
- for (i = 0; i < n; i++) if (a[i][k])
- for (j = 0; j < n; j++)
- c[i][j] += a[i][k] * b[k][j];
- for (i = 0; i < n; i++)
- for (j = 0; j < n; j++)
- a[i][j] = c[i][j];
- }
- inline int sqr(int x) {
- return x * x;
- }
- int dp[38][8];
- int dfs(int v, int e) { // v为剩余的分数, e为结尾的数字
- if (!v)
- return 1;
- if(~dp[v][e]) return dp[v][e];
- dp[v][e] = 0;
- int &ret = dp[v][e], i;
- for (i = 0; i < b; i++)
- if (i != e) if(v >= sqr(i-e))
- ret += dfs(v - sqr(i - e), i);
- return ret;
- }
- int main() {
- int i, j, k, cas;
- scanf("%d", &cas);
- for (int ca = 1; ca <= cas; ca++) {
- scanf("%d%d", &b, &s);
- printf("Case %d: ", ca);
- X = (b - 1) * (b - 1);
- n = X * b;
- if (b == 2) {
- puts("1");
- continue;
- }
- memset(dp, -1, sizeof(dp));
- LL sum = 0;
- if (s <= X) {
- for (i = 1; i < b; i++) //注意没有前导零
- sum += dfs(s, i);
- printf("%u\n", sum);
- continue;
- }
- for (i = 1; i <= X; i++)
- for (j = 0; j < b; j++) {
- B[(i - 1) * b + j] = dfs(i, j);
- //记忆化搜索出 B[]初始状态 分数为1----(b-1)*(b-1), 以0---b结尾
- }
- s -= X;
- //构造单位矩阵A
- for (i = 0; i < n; i++)
- for (j = 0; j < n; j++) {
- ans[i][j] = (i == j);
- A[i][j] = 0;
- }
- for (i = 0; i < n - b; i++)
- A[i + b][i] = 1;
- for (i = 1; i <= X; i++)
- for (j = 0; j < b; j++)
- for (k = 0; k < b; k++) if(j != k)
- if (sqr(j - k) == X+1-i) {
- A[(i-1) * b + k][(X - 1) * b + j]++;
- }
- // ans = A^s
- while (s > 0) {
- if (s & 1) mult(ans, A);
- mult(A, A);
- s >>= 1;
- }
- for (i = 0; i < n; i++)
- for (j = n-b+1; j < n; j++)
- sum += B[i] * ans[i][j];
- //取出以1-----b结尾的 数值 (题目的没有前导零可以转化成 结尾不为零)
- printf("%u\n", sum);
- }
- return 0;
- }
- light Oj 1172 二维DP+矩阵 UVa中等题
- light Oj 1172 二维DP+矩阵 UVa中等题
- [中等] UVa OJ 804 Petri Net Simulation
- [中等] Uva OJ 1608 Non-boring sequences
- [中等] UVa OJ 12186 Another Crisis
- [中等] UVa OJ 1395 Slim Span
- light oj 1032 数位DP
- light OJ 1205 数位DP
- light OJ 1068 数位DP
- light oj 1140 数位dp
- light oj 1422,区间dp
- Light OJ 1231(背包dp)
- light oj 1068(数位dp)
- light oj 1422(区间dp)
- light oj 1025 区间dp
- light oj 1032(数位dp)
- Light OJ 1038(概率DP)
- Light OJ 1031 区间dp
- 关于指针
- 解决IE6浏览器下position:fixed固定定位问题
- dynamic_cast
- mysql进不去
- padding与margin的区别
- light Oj 1172 二维DP+矩阵 UVa中等题
- MYSQL笔记
- 完美解决IE6不支持position:fixed的bug
- rails live on the edge: 安装rails 4
- 代码自动提示
- MyEclipse8 中安装Freemarker插件
- UVa 1440 只有下界的最小流
- 字符串处理Keep Deleting
- POJ3352--Road Construction