sdut2879 枚举起点DP

这个题和乌龟棋之类的DP差不多要学会缩减状态

就是,,我们只需枚举当前这个人是谁,选什么颜色,A用了多少,B用了多少

C用了多少我们就不用枚举了,知道选了多少人,A,B用了多少,你还不知C用了多少么,因为总共只有这三种颜色

然后结尾不能与开头相同。。我郁闷了好久。。因为并不能直接知道开头是什么状态。。

那么一种想法就是枚举开头的三种情况(如果有的话),做三次DP,直接调用全局变量就能知道开始时是什么颜色

我写了个记忆化搜索,TLE了,改成DP应该能过

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s[100];
int col[4],cf;//first color
int dp[55][3][55][55];
int dfs(int x,int cx,int c0,int c1){
    // printf("pos:%d col:%d c0:%d c1:%d\n",x,cx,c0,c1);
    if(dp[x][cx][c0][c1]!=-1) return dp[x][cx][c0][c1];
    if(x==col[3]){
        //这里用枚举
        if(cx!=cf) return dp[x][cx][c0][c1]=1;
        return dp[x][cx][c0][c1]=0;
    }
    int ans=0;
    for(int i=0;i<3;++i){
        if(i!=cx) {
            if(i==0&&col[0]-c0<=0) continue;
            if(i==1&&col[1]-c1<=0) continue;
            // if(i==2&&col[2]+c0+c1>=col[3]) continue;
            if(i==2&&col[2]-(x-c0-c1)<=0) continue;
            if(i==0){
                ans+=dfs(x+1,i,c0+1,c1);
            }
            else if(i==1){
                ans+=dfs(x+1,i,c0,c1+1);
            }
            else{
                ans+=dfs(x+1,i,c0,c1);
            }
        }
    }
    return ans;
}
void solve(){
    int i,j,k,p;

    for(i=col[3];i>=1;--i){
        for(j=0;j<3;++j){
            for(k=0;k<)
        }
    }
}
int main(){
    //3^12 约等于 50000+
    int T;scanf("%d",&T);
    while(T--){
        scanf("%s",s);
        int len=strlen(s),i;
        memset(col,0,sizeof(col));
        memset(dp,-1,sizeof(dp));
        for(i=0;i<len;++i){
            col[s[i]-‘A‘]++;
        }
        col[3]=len;
        int res=0;
        for(i=0;i<3;++i){
            cf=i;
            if(col[i]>0)

        }
        printf("%d\n",res);
    }
    return 0;
}
时间: 2024-10-15 01:38:59

sdut2879 枚举起点DP的相关文章

HDU 3709 Balanced Number 枚举+数位DP

枚举支点之后数位DP,注意姿势 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list&g

HDU 5965 枚举模拟 + dp(?)

ccpc合肥站的重现...一看就觉得是dp 然后强行搞出来一个转移方程 即 根据第i-1列的需求和i-1 i-2列的枚举摆放 可以得出i列摆放的种类..加了n多if语句...最后感觉怎么都能过了..然而不是t就是wa..最后看别人的题解 我的dp转移是9*O(n)的 常数要t.. 别人的题解居然都是用模拟的..根据枚举第一列可以得出第二列的摆放姿势 由这两个摆放和第二列的需求可以求出来第三列..以此类推 最后check一下最后两个.. 叉姐的题解里面写了一个dp转移方程..然而并不能看懂..放牛

Educational Codeforces Round 61 (Rated for Div. 2)F(区间DP,思维,枚举)

#include<bits/stdc++.h>typedef long long ll;const int inf=0x3f3f3f3f;using namespace std;char b[507];int dp[507][507];int main(){    memset(dp,0x3f,sizeof(dp));    int n;    scanf("%d",&n);    scanf("%s",b+1);    for(int i=1;

POJ:1050(枚举 + DP)

1 #include <stdio.h> 2 #include <math.h> 3 #include <iostream> 4 #include <string.h> 5 #include <algorithm> 6 using namespace std; 7 #define N 105 8 int f[N][N]; 9 int sum[N][N]; 10 int main(){ 11 int n; 12 while(scanf("

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

poj 1141 Brackets Sequence(线性dp)

题意:给出一个括号串,求最短的满足要求的括号串: 思路:枚举长度,枚举起点和终点,找到匹配括号是可递推到子序列,枚举中间指针求最优解:打印时通过记忆表path存储最优解,递归求出最短序列: #include<cstdio> #include<cstring> #include<algorithm> #define INF 0x7fffffff using namespace std; char str[505]; int dp[505][505]; int path[5

UVA 10641 - Barisal Stadium(DP + 几何)

题目链接:10641 - Barisal Stadium 题意:逆时针给定n个点,在给m个灯,每个灯有一个花费,要求最小花费使得所有边能被灯照到 思路:用向量叉积判断向量的顺逆时针关系,从而预处理出每个灯能照到的边,然后由于n个点是环的,所以可以直接扩大两倍,dp时候去枚举起点即可 状态为dp[i]表示现在照到i条边之前的边全部照亮需要的最小花费 代码: #include <stdio.h> #include <string.h> const double eps = 1e-6;

【算法学习笔记】85.破环为链 序列DP 松弛+代价 SJTU OJ 1073 能量项链

和石子合并很像, 为了对环状进行处理, 我们可以把输入数据复制一份接连在后边. 这样在最后的结果枚举起点找最大即可. 注意这里代价的计算, 因为我们的data[i]只记录了珠子的头珠子的尾部即是下一个珠子的头部. //因为计算dp[i][j]时需要 用到dp[i][k] k比j小 所以j顺序 dp[k][j] k比i大 所以i逆序 k插入即可 for (int i = 2*n-1; i >=1 ; --i){ for (int j = i; j <= 2*n; ++j){ dp[i][j] =

poj 3071 概率dp

//分析:明显的树形关系,题目描述的是一棵高 n + 1的完全二叉树,则 dp[树层号][team号](规定最底层为 0 层,层数朝节点的方向依次递增),推一下就好了 //稍微需要想一下的是比赛双方的选取,下面给出两种方法 //#1 枚举起点划分team区间 1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm"