dp洋洋散散的知识+code

/*在数轴上有0-N的位置
从0出发每次可以向右走
2
23
233步*/

// 1 总共的方案数

f[i]=f[i-2]+f[i-23]+f[i-233];

        f[0]=1;
    for (int a=1;a<=n;a++)
    {
        if (a>=2) f[a]+=f[a-2];
        if (a>=23) f[a]+=f[a-23];
        if (a>=233) f[a]+=f[a-233];
    }
    printf("%d\n",f[n]);

// 2 考虑恰好t次到达时
//dp 题 可以考虑 每多一个条件 数组就多一维;所以,开二维数组
//f[i][j] 表示 用 j 步走了i种方案

f[i][j]=f[i-2][j-1]+f[i-23][j-1]+f[i-233][j-1];

        f[0][0]=1;
    for (int a=1;a<=n;a++)
        for (int b=1;b<=t;b++)
        {
            if (a>=2) f[a][b]+=f[a-2][b-1];
            if (a>=23) f[a][b]+=f[a-23][b-1];
            if (a>=233) f[a][b]+=f[a-233][b-1];
        }
    printf("%d\n",f[n][t]);
        int ans=0;
    for (int a=0;a<=t;a++)
        ans+=f[n][a];
    printf("%d\n",ans);

//  3 考虑小于t次
//将
f[n][1]+f[n][2]+....f[n][t];

//考虑最多走r步233
//so 要再加一维,变成三维数组
//f[i][j][k] 表示走到 i点,公用j步,走233用了k步

f[i][j][k]=f[i-2][j-1][k]+ f[i-23][j-1][k]+ f[i-233][j-1][k-1];
/*
(N,M)的方格图
从(0,0)开始
只能朝右或上走
问走到(N,M)的方案数*/ 

//将每个点的左边点和下边点相加

f[n][m]=f[n-1][m]+f[n][m-1];

//考虑有k个点(x,y)不能走
//定义布尔数组记录每个不能坐的点
每次设f[x][y]=0,并加以判断;

//2.考虑每个坑只能掉一次:
if(不是坑)

F[i][j][k]=f[i-1][j][k]+f[i][j-1][k];

else if(是坑)

F[i][j][1]=f[i-1][j][0]-f[i][j-1][0];

#include<iostream>
using namespace std;
int main()
{
    int n,i,j,a[101][101];
    cin>>n;
    for (i=1; i<=n; i++)
        for (j=1; j<=i; j++)
            cin>>a[i][j];                             //输入数字三角形的值
    for (i=n-1; i>=1; i--)
        for (j=1; j<=i; j++)
        {
            if (a[i+1][j]>=a[i+1][j+1])
            a[i][j]+=a[i+1][j];     //路径选择
            else  a[i][j]+=a[i+1][j+1];
        }
    cout<<a[1][1]<<endl;
}

int fib(int a)
{
    if (!a) return 0;
    if (a==1) return 1;
    if (g[a]) return f[a];
    g[a]=true;
    f[a]=fib(a-1)+fib(a-2);
    return f[a];
}
 数字三角形问题,使得答案对p取模最大?

F[i][j][k] 表示走到第i行第j列 使得答案模p是否可行

F[i][j][k]=f[i+1][j][k-v[i][j]]
Or
F[i+1][j+1][k-v[i][j]]
**********代码:

    for (int a=1;a<=n;a++)
        f[n][a][v[n][a]%p]=true;
    for (int a=n-1;a>=1;a--)
        for (int b=1;b<=a;b++)
            for (int c=0;c<p;c++)
                f[a][b][c]=
                    f[a+1][b][(c-v[a][b]+p)%p] ||
                    f[a+1][b+1][(c-v[a][b]+p)%p];
    int ans;
    for (int a=p-1;a>=0;a--)
        if (f[1][1][a])
        {
            ans=a;
            break;
        }

//***********区间DP******** 

/*合并石子

每次选择相邻两堆

代价为两堆石子和

问最小总代价

(第一层for循环一定要正着写)

因为后一层循环需要前一层循环的数据 */

F[l][r]=min(f[l][k]+f[k+1][r]+sum[l][r])

/*矩阵乘法
自定义顺序
使得运算次数最少*/

//F[i][j] 表示搞定[I,j]的最小代价
F[i][j] = min(f[i][k]+f[k][j+1]+cost(I,k,j))
    
时间: 2024-10-14 08:31:35

dp洋洋散散的知识+code的相关文章

CSU1620: A Cure for the Common Code(KMP+区间DP)

Description Input Output Sample Input abcbcbcbca abbbcdcdcdabbbcdcdcd 0 Sample Output Case 1: 7 Case 2: 11 HINT Source 题意:把字符串简化,问简化得到的最短长度是多少 思路:要简化首先要求循环节,这里用kmp解决,而要求所有简化中最短的的话,用区间dp可以求得 <pre name="code" class="cpp">#include &

HDU 4293 Groups(区间dp)

HDU 4293 题意:有 n 个人,可任意分成若干组,然后每个人各提供一个信息,表示他们组前面有多少个人,后面有多少个人.问最多有多少个信息是真实的的. 思路: 这道题一开始给我的印象是什么乱七八糟的东西,后来也没想通到底该怎么做,好在赛后百度在手天下我有:) 我们可以把 这n个人看成一段区间 [1,n]. 设每个人的信息是a.b,则这个信息代表了他们组所在的区间 [a+1,n-b]. 若a+b>n,显然撒谎,跳过不做处理. 我们用一个Map[i][j]数组将同在一区间[i,j]的人数纪录下来

BZOJ 3892 Usaco2014 Dec Marathon DP

题目大意:给出平面上的一些点,要求按顺序遍历,费用是两点之间的曼哈顿距离,可以跳过k次,问最少需要花费多少. 思路:O(n^3)dp就行了. CODE: #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 510 using namespace std; struct

动态规划(DP),压缩状态,插入字符构成回文字符串

题目链接:http://poj.org/problem?id=1159 解题报告: 1.LCS的状态转移方程为 if(str[i-1]==str[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 2.由于开不了dp[5005][5005],于是考虑到压缩状态 这里采用滚动数组方式,LCS的状态转移方程可以改写为 if(str1[i-1]==str2[j-1]) { dp[i%2][j]=dp[(i-1

POJ 2096 Collecting Bugs:期望dp

题目链接:http://poj.org/problem?id=2096 题意: 有一个程序猿,他每天都会发现一个bug. bug共有n个种类.属于某一个种类的概率为1/n. 有s个子系统,每个bug属于一个系统.属于某一个系统的概率为1/s. 问你发现的bug能够覆盖到n个种类和s个系统的期望天数. 题解: 期望dp转移的套路: 倒着推. 利用性质:期望 = ∑ (P(子期望)*φ(子期望)) 状态表示: dp[i][j] = expectation i:覆盖到i个种类 j:覆盖到j个系统 dp

RQNOJ 188 购物问题:树形dp

题目链接:https://www.rqnoj.cn/problem/188 题意: 商场以超低价格出售n个商品,购买第i个商品所节省的金额为w[i]. 为了防止亏本,有m对商品是不能同时买的.但保证商品关系不出现环,不会出现如:(1,2) , (2,4) , (1,4). 问你最多能节省的金额. 题解: 简直和POJ 2342 Anniversary party像极了(*/ω\*) 将不能同时买的商品间连一条无向边. 所以子节点和父节点不能同时选. 唯一不同的是POJ是一棵树,而这道题是一片森林

HDU 1176 免费馅饼:dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1176 题意: 横坐标范围为[0,10],你在第0秒站在坐标为5的地方. 在接下来的一段时间内,会有n个馅饼落下来,每一个馅饼有一个位置x和时刻t. 每一秒你最多可以移动1格.并且在某一个时刻,你只能接到你当前位置的馅饼. 问你最多能接到多少馅饼. 题解: 表示状态: dp[i][j] = max num of pancakes (1)第i秒 (2)站在j的位置 如何转移: 当前dp[i][j]取决于

插头DP小结

首先是CDQ<基于连通性状态压缩的动态规划问题>论文上的题目: URAL 1519 Formula 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 15; 6 const int HASH = 30007; 7 const int SIZE = 1000010; 8 typedef long lon

BZOJ 1592 Usaco 2008 Feb Making the Grade 路面修整 DP

题目大意:给出一个不整齐的路面,可以将一个路面升高或者降低,都需要话费|x - x'|的费用,把路面修正成单调不降或单调不升的最小花费是多少. 思路:路面的高度跨度有点大啊,先离散化.之后f[i][j] 表示到i为止路面保证单调不降并且最高高度为j的最小花费是多少,利用一个前缀和优化一下.单调不升也一样,简单DP水过.. CODE: #include <map> #include <cstdio> #include <cstring> #include <iost