uva 580 - Critical Mass(dp)

题目链接:uva
580 - Critical Mass

题目大意:给定一个栈,向栈里连续添加n次,每次可以添加U或者L,如果出现连续三个U则为不安全,问有多少种不安全的可能。

解题思路:先求出安全的,用总数减去安全的即为答案。

dp[i][j]表示以第i个位置结尾时,有末尾有j个连续的U。

还有一种解法,dp[i]表示第i个位置以L结尾的总数,dp[i] = dp[i-1] + dp[i-2] + dp[i-3];

解法一:
#include <cstdio>
#include <cstring>

typedef long long ll;
ll dp[40][3];

ll solve (int n) {
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;

    for (int i = 1; i <= n; i++) {

        for (int j = 0; j < 3; j++)
            dp[i][0] += dp[i-1][j];

        for (int j = 1; j <= 2; j++)
            dp[i][j] = dp[i-1][j-1];
    }
    ll ans = 0;
    for (int i = 0; i < 3; i++)
        ans += dp[n][i];
    return (1LL<<n)-ans;
}

int main () {
    int n;
    while (scanf("%d", &n) == 1 && n) {
        printf("%lld\n", solve(n));
    }
    return 0;
}
解法二:
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
ll dp[40];

ll solve(int n) {

    memset(dp, 0, sizeof(dp));
    dp[0] = dp[1] = 1;
    for (int i = 2; i <= n; i++) {

        for (int j = 1; j <= min(3, i); j++)
            dp[i] += dp[i-j];
    }

    ll ans = 0;
    for (int i = 0; i <= min(n, 2); i++)
        ans += dp[n-i];
    return (1LL<<n)-ans;
}

int main () {
    int n;
    while (scanf("%d", &n) == 1 && n) {
        printf("%lld\n", solve(n));
    }
    return 0;
}

uva 580 - Critical Mass(dp)

时间: 2024-10-14 14:09:44

uva 580 - Critical Mass(dp)的相关文章

UVA 580 - Critical Mass(DP)

题目链接:580 - Critical Mass 题意:一个栈,里面可以放L和U,有三个连续的U就是不安全的,问共有几种不安全的情况 思路:dp,dp[i][j][k],表示放到第i个,最后两个状态为j,k表示有没有出现不安全.然后去记忆化搜索一下就可以了 然后还有一种做法是,先考虑安全的情况,在用总情况(1<<n 种)减去安全的情况,安全的情况的递推方式很容易dp[i]表示放第i个, dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]. 不过这题都没给数据范围

UVa 580 - Critical Mass(递推)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=521 题意: 有一些装有铀(用U表示)和铅(用L表示)的盒子,数量均足够多.要求把n(n≤30)个盒子放成一行,但至少有3个U放在一起,有多少种放法?例如,n=4, 5时答案分别为3, 8. 分析: 设答案为f(n).既然有3个U放在一起,可以根据"最左边的3个U"

UVA 580 Critical Mass

https://vjudge.net/problem/UVA-580 题意:一堆U和L,用n个排成一排,问至少有3个U放在一起的方案数 f[i] 表示 至少有3个U放在一起的方案数 g[i] 表示没有3个U放在一起的方案数 状态转移: g[i]=2^i-f[i] 枚举 第一次出现3个U的位置j,那么j-1一定是L,前j-2个一定没有3个U放在一起,第j+2个往后随便放 所以 f[i]=2^(i-3) + Σ g[i-2]*2^(i-j-2) 2^(i-3) 是当i=1时,后面的Σ从2开始 #in

uva 580 Critical Mass(递推)

#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; typedef unsigned long long ull; int main() { int i,j,n; ull f[35],a[35],g[35]; a[0]=1; for(i=1;i<=30;i++) { a[i]=a[i-1]*2; } f[0]=f

uva 580 危险的组合(排列组合)

Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description During the early stages of the Manhattan Project, the dangers of the new radioctive materials were not widely known. Vast new factory cities were buil

UVa 1586 Molar mass --- 水题

UVa 1586 题目大意:给出一种物质的分子式(不带括号),求分子量.本题中分子式只包含4种原子,分别为C.H.O.N, 原子量分别为12.01,1.008,16.00,14.01 解题思路:先实现一个从字符型的数到整型的数的转换函数,再将输入的串从头到尾扫描,遇到字母,则进一步扫描后面的数字的区间, 再调用函数进行转换,再乘以其的原子质量,最后累加到sum中即可. /* UVa 1586 Molar mass --- 水题 */ #include <cstdio> #include <

[UVA 12589]Learning Vector[DP]

题目链接:[UVA 12589]Learning Vector[DP] 题意分析:给出n个矢量,从中选择k个,以坐标原点为起点,收尾相连,问:这样的k个周围相连矢量与x轴围成图形的最大面积的两倍是多少? 解题思路:考虑状态:dp[id][pick][h]代表到第id个矢量为止,选择pick个矢量离最大面积还差多少,h为当前图形最右端高度.具体转移看代码. 这里着重说一下为什么要对这些矢量按斜率进行排序: 首先,整个求解过程其实就是在暴力枚举这些向量的组合,只不过采用了记忆化搜索优化. 其次,对于

uva 1586 - Molar mass

在想更好的处理方法,现在却只能有这个糟烂的代码了--不好意思 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; const int maxn=200; char s[maxn]; double ans[maxn]; int get_num(int pos,int len) { int temp; for(int i=pos;i<len;i++) { if(s[i

Uva 12018 Juice Extractor dp

题目链接:点击打开链接 题意: 切水果游戏 给出n个水果 水果出现在屏幕上的时间的区间 1.每次切会把屏幕上所有水果切完 2.当同时切3个或以上时计分,分数为切的水果个数 3.不能遗漏水果 问最高得分 dp[i] 表示 最后一次切第i个的得分. #include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; #define N 1