Codeforces Round #461 (Div. 2) C、E

C

题意

给定 n n ,给定 k k
求是否有 i < j k i<j ≤ k ,满足 n % i = n % j n\%i=n\%j

题解

n % 1 = 0 n\%1=0
如果没有的话,那么。
n % 1 , n % 2 , . . . , n % k n\%1,n\%2,...,n\%k 两两不等
然后会发现只会存在, n % i = i 1 n\%i=i-1
换句话说, ( n + 1 ) % i = 0 (n+1)\%i=0
也就是, n + 1 = l c m ( 1 , 2 , . . . , k ) n+1=lcm(1,2,...,k)
阶乘式增长,又因为 n 1 e 18 n\leq 1e18
所以枚举即可。

#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define sf(x) scanf("%d",&x)
using namespace std;
typedef long long ll;
const int maxn = 250050;
 
vector<int>G[maxn];
int A[maxn],c[maxn][10],col[maxn],Color[maxn];
int dep[maxn];
ll ans=0x3f3f3f3f3f3f3f3f,ret;
 
 
int main(){
    ll n,k;cin>>n>>k;
    for(int i=1;i<=k;i++){
        if((n%i)!=(i-1)){
            puts("No");
            return 0;
        }
    }
    puts("Yes");
}

E

题意

每棵树有 c i c_i 只鸟,召唤一只鸟需要 c o s t i cost_i 点法力,召唤一只会给自己增加 B B 的法力上限,走完一棵树会加上 X X 法力值,求最多召唤多少只鸟

题解

显然 d p dp
关键是怎么得到当前状态的法力值,并且知道当前法力上限。
如果要知道法力上限,一定要知道打了多少只鸟。
所以状态要记录鸟的数量,既然记录了鸟的数量,那么 d p dp 值就无所谓了,可以用来记录法力值。显然对于同样召唤的鸟数法力值越多越好

1 -1 表示到达不了这种状态,方便转移,我们把每天结束后增加的 X X 算到当天。
可以均摊 n 2 n^2 的复杂度。
每次枚举当前鸟数,在枚举在这棵树召唤的鸟数即可。
不召唤的话,直接 + X +X ,和法力上限取 m i n min
召唤的话,先减去花费,再加上 X X ,取 m i n min

如果能想到法力上限这道题就结束了。
但是还是靠队友提示的,希望好好努力把。
训练期间老找队友真不是一种好习惯。

#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define sf(x) scanf("%d",&x)
using namespace std;
typedef long long ll;
const int maxn = 250050;

string str[maxn];

struct node{
    int s,h;ll tmp;
    int id;
    friend bool operator < (node a,node b){
        return 1ll*a.s*b.h>1ll*b.s*a.h;
    }
}A[maxn];

int c[maxn],cost[maxn],pre[maxn];
ll dp[1050][10050];

int main(){
    int n,W,B,X;
    cin>>n>>W>>B>>X;
    FOR(i,1,n)sf(c[i]),pre[i]=pre[i-1]+c[i];
    FOR(i,1,n)sf(cost[i]);
    memset(dp,-1,sizeof(dp));
    dp[0][0]=W;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=pre[i-1];j++){
            if(dp[i-1][j]==-1)continue;
            dp[i][j]=max(min(dp[i-1][j]+X,W+1ll*B*j),dp[i][j]);
        }
        for(int j=0;j<=pre[i];j++){
            for(int k=0;k<=c[i]&&k<=j;k++){
                if(dp[i-1][j-k]<1ll*k*cost[i])continue;
                ll tmp=dp[i-1][j-k]-1ll*k*cost[i];
                dp[i][j]=max(min(tmp+X,W+1ll*B*j),dp[i][j]);
            }
        }
    }
    int ans=0;
    for(int i=0;i<=pre[n];i++){
        if(dp[n][i]==-1)continue;
        ans=max(ans,i);
    }
    cout<<ans<<endl;
}

发布了203 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/mxYlulu/article/details/104129155
今日推荐