0
点赞
收藏
分享

微信扫一扫

完全背包+数学思维

惠特曼 2022-05-02 阅读 40

C. Palindrome Basis
先将所有回文整数预处理出来,然后可看作完全背包。
f[j]表示组成n的方案数
状态转移方程: f[j]=(f[j]+f[j-a[i]])%mod;

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const int N=4005;
int a[N],f[N],cnt;
int check(int x)
{
    int b[10]={0},k=0;
    while(x)
    {
        b[++k]=x%10;x/=10;
    }
    int i=1,j=k;
    while(i<=j)
    {
        if(b[i]==b[j])
            i++,j--;
        else
            return 0;
    }
    return 1;
}
int main()
{
    for(int i=1;i<=4000;i++)
        if(check(i))
            a[++cnt]=i;
    /*for(int i=1;i<=30;i++)
        cout<<a[i]<<" ";
    cout<<endl;*/
    f[0]=1;
    for(int i=1;i<=cnt;i++)
    {
        for(int j=a[i];j<=4000;j++)
        {
            f[j]=(f[j]+f[j-a[i]])%mod;
        }
    }
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        cout<<f[n]<<endl;
    }
    return 0;
}



D. Lost Arithmetic Progression
这题难度估计在1800以上了。
思路倒是看明白了,但难点应该在于多种情况的讨论,不能缺失。
本题一篇很好的博客

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod =1e9+7;
ll b,q,y,c,r,z;
int main() 
{
	int t;cin>>t;
	while (t--) 
    {
		scanf("%lld%lld%lld", &b, &q, &y);
        scanf("%lld%lld%lld", &c, &r, &z);
        ll bb=b+(y-1)*q, cc=c+(z - 1)*r;
    //情况不存在的
        if (b>c||(r%q)||((c-b)%q)||(bb<cc)||(c>bb)||(b>cc)) 
        {
            puts("0");
            continue;
        }
    //无穷多个
        if(b+r>c||(bb<cc+r)) 
        {
            puts("-1");
            continue
        }
        ll res=0;
    //数组A和B的最大公因数为C
        for (ll i=1; i<=r/i; i++)
        {
            if(r%i) 
                continue;
            ll t=i;
            if (t*q /__gcd(t,q)==r) {
                (res +=(r/t)*(r/t)%mod)%=mod;
            }
 
            if (i*i==r) 
                continue;
            t=r/i;
            if (t*q/__gcd(t,q)==r) 
                (res+=(r/t)*(r/t)%mod)%=mod;
        }
        printf("%lld\n", res);
	}
	return 0;
}
举报

相关推荐

0 条评论