• 题解 P1011 【车站】


    posted on 2019-08-20 22:07:29

    蒟蒻的第一篇题解

    教你怎样打表

    这一道题目其实是个数学题,也不是很难,我们可以先在草稿纸上写一下

    用(x,y)代表a和b的系数

    1 2 3 4 5 6
    上车u (1,0) (0,1) (1,1) (1,2) (2,3) (3,5)
    下车d (0,0) (0,1) (0,1) (1,1) (1,2) (2,3)
    增量△ (0,0) (0,0) (1,0) (0,1) (1,1) (1,2)
    剩余r (1,0) (1,0) (2,0) (2,1) (3,2) (4,4)

    我们发现,从3开始的增量与前数两个的上车数相等,即

    △_i=u_(i-2) ,if(i>=3)

    由题目

    d_i=u_(i-1) ,if(i>=3)

    因此,我们完全可以将第i个车站对应的剩余人数r预处理打表出来

    打表程序如下


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    int a[21][5][3];
    int main()
    {
    	freopen("pra.txt","w",stdout);
    	a[1][1][1]=1;
    	a[1][4][1]=1;
    	a[2][1][2]=1;
    	a[2][2][2]=1;
    	a[2][4][1]=1;
    	for(int i=3;i<=20;i++)
    	{
    		for(int k=1;k<=2;k++)
    		{
    			a[i][1][k]=a[i-2][1][k]+a[i-1][1][k];
    			a[i][2][k]=a[i-1][1][k];
    			a[i][3][k]=a[i][1][k]-a[i][2][k];
    			a[i][4][k]=a[i-1][4][k]+a[i][3][k];
    		}
    	}
    	for(int i=1;i<=20;i++)
    	{
    		cout << i << endl;//这里是为了打出来后先检查一遍是否正确
    		for(int j=1;j<=4;j++)
    		{
    			for(int k=1;k<=2;k++)
    			{
    				cout << a[i][j][k] << ",";
    			}
    			cout << endl;
    		}
    		cout << endl;
    	}
    	fclose(stdout);
    return 0;
    }
    

    科学的打表在一些数据范围大的题中很有帮助
    上述程序运行后得到以下内容

    1
    1,0,
    0,0,
    0,0,
    1,0,
    
    2
    0,1,
    0,1,
    0,0,
    1,0,
    
    3
    1,1,
    0,1,
    1,0,
    2,0,
    
    4
    1,2,
    1,1,
    0,1,
    2,1,
    
    5
    2,3,
    1,2,
    1,1,
    3,2,
    
    6
    3,5,
    2,3,
    1,2,
    4,4,
    
    7
    5,8,
    3,5,
    2,3,
    6,7,
    
    8
    8,13,
    5,8,
    3,5,
    9,12,
    
    9
    13,21,
    8,13,
    5,8,
    14,20,
    //太长了所以就复制了前9个
    

    然后可以将打出来的表与自己找规律找出来的几个值对比来确认是否正确


    确认后即可删去代码中的endl和cout << i << endl;
    修改成符合题目条件的格式,再复制粘贴


    正式程序如下

    #include <iostream>
    using namespace std;
    int a,n,m,x;
    int main()
    {
    	int p[20][4][2]={1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,1,0,1,1,0,2,0,1,2,1,1,0,1,2,1,2,3,1,2,1,1,3,2,3,5,2,3,1,2,4,4,5,8,3,5,2,3,6,7,8,13,5,8,3,5,9,12,13,21,8,13,5,8,14,20,21,34,13,21,8,13,22,33,34,55,21,34,13,21,35,54,55,89,34,55,21,34,56,88,89,144,55,89,34,55,90,143,144,233,89,144,55,89,145,232,233,377,144,233,89,144,234,376,377,610,233,377,144,233,378,609,610,987,377,610,233,377,611,986,987,1597,610,987,377,610,988,1596,1597,2584,987,1597,610,987,1598,2583,2584,4181,1597,2584,987,1597,2585,4180};
    	cin >> a >> n >> m >> x;
    	int b=(m-p[n-1-1][3][0]*a)/p[n-1-1][3][1];
    	cout << p[x-1][3][0]*a+p[x-1][3][1]*b;
    return 0;
    }
    

    因为我把列表中四个数据都打出来了,所以就开了个三维数组进行储存,其实可以只留剩余人数r


    最后还有易错点,坑了我两次提交

    我的三维数组都是从0开始的,但是一开始我按照从1开始做的,可惨了orz,所以希望大家一定要严谨,毕竟WA事小,最后白费了几年努力就不好了

    蒟蒻的第一篇题解(如何打表)谢谢大家,希望能过

  • 相关阅读:
    CF799B T-shirt buying
    luogu3469 [POI2008]BLO_Blockade
    luogu2746 校园网
    USACO 2.2 Party Lamps 【高能等效+规律枚举】
    USACO 2.2 Subset Sums 【经典的方案DP+必要的转化】
    USACO 2.2 Preface Numbering 【实质是分治思想】
    bzoj 1051: [HAOI2006]受欢迎的牛 (Tarjan 缩点)
    bzoj 1088: [SCOI2005]扫雷Mine
    bzoj 2761: [JLOI2011]不重复数字 (map||Treap)
    bzoj 1230: [Usaco2008 Nov]lites 开关灯
  • 原文地址:https://www.cnblogs.com/xuanfly/p/11808517.html
Copyright © 2020-2023  润新知