动态规划

1.2021/2/4的ppt"动态规划 .PDF"

多段图问题 模型

阶段 ,状态,决策,状态转移方程

无后效性

动态规划和贪心的不同

2.

多多看DVD问题 :

i是阶段,(j,k)是每个阶段里面的状态 ,所以i的顺序不能乱 ,但是可以是(j, k)也可以是(k, j);

 

3.如果问题是由交叠的子问题所构成,我们就可以用动态规划技术来解决它

 

4.背包问题 之 为什么a[0][0~k]为什么都要赋值成0,不应该只有a[0][0]的状态才是存在的吗?

-》当a[n-1][c]再装一件物品也不能刚好使用 k的空间时,那么通过a[0][2(举个例子)]这个虚拟状态(总空间只有k-2的情形)转移过来的方 程就可以达到刚好使用k-2的空间,从而更新a[n][k]

-》因为空间更少得到的答案只能少不可能多,保证了答案的正确性

-》本来for(1~k) ans = max(f[n][i],ans)也能找到答案,但这样自动赋初值的方法简化了这一步!!

 

5.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <iomanip>
using namespace std;
const int N = 110;
const int M =  1e4+10;
int n, m, t, f[N][M];
/*
void  input()
{
    cout<<"start"<<endl;
    for(int i = 0; i <= n; i++)
    {
        for(int j = 0; j <= m; j++)
        {
            cout << setw(4)<<f[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<"end"<<endl;
}
*/
int main()
{
    scanf("%d %d",&n, &m);
    //for(int i = 0; i <= n; i++)
        f[0][0] = 1;
    //input();
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &t);
        for(int j = 0; j <= m; j++)
        {
            if(j>=t) f[i][j] +=  f[i-1][j-t];
            f[i][j]  += f[i-1][j];
        }
    }
    //input();
    printf("%d", f[n][m]);
    return 0;
}
有多少种 刚好装满背包 的问题

第i种物品可以 由两种状态转叠加过来,i-1的物品的j类,或者i-1物品的j-t类(t空间来装本物品)

 

6.多重背包

 

7.最长不升子序列问题

 

8.最长公共子序列

 

9.一个 大佬的发言

 

10.未解之题

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 110;
int a[N], b[N];
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    int ans = 0;
    for(int k = 1; k <= n; k++)
    {
        int sum = 1;
        int len = 0;
        for(int i = 1; i < k; i++)//求最长下降序列
        {
            if(a[i]>=a[k]) continue;
            if(len==0) b[++len] = a[i];
            else
            {
                if(a[i]>a[len]) b[++len] = a[i];
                else
                {
                    int pos = lower_bound(b+1, b+1+len, a[i])-b;
                    b[pos] = a[i];
                }
            }
        }
        sum += len;
        len = 0;
        for(int i = k+1; i <= n; i++)//求最长下降序列
        {
            if(a[i]>=a[k]) continue;
            if(len==0) b[++len] = a[i];
            else
            {
                if(a[i]<a[len]) b[++len] = a[i];
                else
                {
                    int pos = lower_bound(b+1, b+1+len, a[i], greater<int>())-b;
                    b[pos] = a[i];
                }
            }
        }
        sum += len;
        ans = max(ans, sum);
    }
    printf("%d", n-ans);
    return 0;
}
我也不知道为什么就错了的代码

 

posted @ 2021-02-04 20:00  bear_xin  阅读(69)  评论(0)    收藏  举报