• 解题报告:luogu P1356


    题目链接:P1356 数列的整除性
    lhr大佬问我一道题:
    数字三角形那个题,求得分个位数的最大值。
    然后我竟然秒了。
    这个题其实也是一样的。
    我们容易想到用(dp[i][j])表示前(i)个数(mod k)(j)的方案有无。
    很显然:

    [dp[i][jpm a[i]mod k]=dp[i-1][j] ]

    我们要注意负数取模的处理:

    inline int mod(int n,int p)
    {
    	if(n>=0) return n%p;
    	int g=abs(n)/p;
    	return (n+g*p+p)%p;
    }
    

    然后直接递推就好了。
    有序的(dp)果然简单。
    时间复杂度是(mathcal O(Tnk)),然后就过了。
    对于上面哪那一题,可以用(dp[i][ij][k])代表第(i)行第(j)列,个位数为(k)的方案。
    后来考虑到可以状压,去掉(k)那一维。
    这个题我们就有了空间(mathcal O(nsqrt{k}))的做法,即把得数化成(sqrt{k})进制,然后数组的值进行状压即可。
    不过有些难打,就只写了无脑的做法。

    (Code)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    
    int t,n,a[10005],k;
    int dp[10005][105];
    
    inline int mod(int n,int p)
    {
    	if(n>=0) return n%p;
    	int g=abs(n)/p;
    	return (n+g*p+p)%p;
    }
    
    int main()
    {
    	read(t);
    	while(t--)
    	{
    		memset(dp,0,sizeof(dp));
    		read(n),read(k);
    		for(int i=1;i<=n;i++) read(a[i]);
    		dp[1][mod(a[1],k)]=1;
    		for(int i=2;i<=n;i++)
    		{
    			for(int j=0;j<=k;j++)
    			{
    				if(dp[i-1][j])
    				{
    					dp[i][mod(j+a[i],k)]=1;
    					dp[i][mod(j-a[i],k)]=1;
    				}
    				
    			}
    		}
    		if(dp[n][0]) printf("Divisible
    ");
    		else printf("Not divisible
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    mongodb 的安装历程
    从C的声明符到Objective-C的Blocks语法
    #译# Core Data概述 (转)
    避免在block中循环引用(Retain Cycle in Block)
    GCD和信号量
    Blocks的申明调用与Queue当做锁的用法
    [译]在IB中实现自动布局
    清理Xcode的技巧和方法
    SVN的Status字段含义
    iOS应用崩溃日志揭秘2
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12698046.html
Copyright © 2020-2023  润新知