C
题意
给定
,给定
。
求是否有
,满足
题解
如果没有的话,那么。
两两不等
然后会发现只会存在,
换句话说,
也就是,
阶乘式增长,又因为
所以枚举即可。
#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
题意
每棵树有 只鸟,召唤一只鸟需要 点法力,召唤一只会给自己增加 的法力上限,走完一棵树会加上 法力值,求最多召唤多少只鸟
题解
显然
关键是怎么得到当前状态的法力值,并且知道当前法力上限。
如果要知道法力上限,一定要知道打了多少只鸟。
所以状态要记录鸟的数量,既然记录了鸟的数量,那么
值就无所谓了,可以用来记录法力值。显然对于同样召唤的鸟数法力值越多越好
表示到达不了这种状态,方便转移,我们把每天结束后增加的
算到当天。
可以均摊
的复杂度。
每次枚举当前鸟数,在枚举在这棵树召唤的鸟数即可。
不召唤的话,直接
,和法力上限取
召唤的话,先减去花费,再加上
,取
如果能想到法力上限这道题就结束了。
但是还是靠队友提示的,希望好好努力把。
训练期间老找队友真不是一种好习惯。
#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;
}