zoukankan      html  css  js  c++  java
  • Week13 作业 C

    题目描述:

    思路:

    • 符合最优子结构

    • 定义状态:f[i][j]表示在第i秒结束时,位置在j处能接到的总量的最大值

    • 状态转移:f[i][j]= max(f[i - 1][j - 1], max(f[i-1][j], f[i-1][j+1])) + d[i][j],即位置j可以从j-1,j,j+1三个位置转移过来

    • 边界条件:f[0][j]=0,第0秒包里一定是空的

    • 答案:max{f[T][j]},T表示最后的时间

    • 这样对吗???不对,因为f[T][j]不知道是由谁转移过来的,进一步也就没法确定f[T][j]的起始状态是不是在5号点,所以信息不足,难道要增加维度吗?

    • 其实,可以逆序搜索,相当于把时间倒放,f[0][5]是最后的状态,这样就能符合题目要求了,状态转移和边界条件上述稍微一修改即可,思想不变

    总结:

    题目限制了状态的转移,则就要考虑当前状态是不是合法的

    代码:

    因为为了使用第一次定义的状态转移,为了防止数组下标为负,把坐标统统加了1(全部向右移动一个单位),不过因为发现逆序才更好,所以没啥用,但是懒得改了

    //设f[i][j]表示在第i秒结束时,位置在j处能接到的猫的最大值
    //	f[i][j]= max(f[i - 1][j - 1], max(f[i-1][j], f[i-1][j+1])) + d[i][j];
    //因为用到i-1,所以把整个坐标轴向右平移1个单位
    //初始化f[0][j]=0;
    //问题:必须从位置5开始,但是最后的位置是不确定的,可以逆着来
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1e5 + 5;
    int f[MAXN][15], d[MAXN][15];
    int main()
    {
    	int M;
    	while (scanf("%d", &M) && M != 0)
    	{
    		memset(f, 0, sizeof(f));
    		memset(d, 0, sizeof(d));
    		int maxT = 0;
    		for (int i = 1; i <= M; i++)
    		{
    			int t, x;
    			scanf("%d %d", &x, &t);
    			d[t][x + 1]++;
    			maxT = max(t, maxT);
    		}
    		for (int i = maxT; i >= 0; i--)
    		{
    			for (int j = 1; j <= 11; j++)
    			{
    				f[i][j] = max(f[i + 1][j - 1], max(f[i + 1][j], f[i + 1][j + 1])) + d[i][j];
    			}
    		}
    		cout << f[0][6] << endl;
    	}
    	return 0;
    }
  • 相关阅读:
    python中字典一键多相同值反转技巧
    win10下安装mysql
    上台阶问题的具体走法用python来实现
    桥接模式
    适配器模式
    多线程中lock的使用
    原型模式
    多线程
    建造者模式
    代理模式
  • 原文地址:https://www.cnblogs.com/qingoba/p/13069246.html
Copyright © 2011-2022 走看看