标签:min cstring https gis htm ide 不能 efi 十分
Oh,no!!又一次出卡特兰数,又一次翻车,还是没有看出来??!!
可能是这次立志要刚出来一个dp题,所以就没怎么往数学那里想
不说了,40%的dp写了2个小时
很好的一道思维题
首先每个缸都可以求出来最多能喝多少次,然后按照从小到大排序
一个十分显然的性质就是,前面的够删的话,后面的也够
从前往后枚举每个缸,比较这个缸剩余的删除次数和后面缸的个数
如果大于,那么就相当于这个缸对答案的贡献是其能减的层数,也就是已经进行的轮数,取余之后,
也就是在这一轮,看这个缸还能不能对ans做贡献,如果这个id之前还能删的缸的个数大于了当前的res值,那就不能,否则+1
注意两个特判
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<vector> 5 #include<cstdlib> 6 #include<cstring> 7 #include<algorithm> 8 #define R register 9 #define int long long 10 using namespace std; 11 const int maxn=100005; 12 int n,m,k,a[maxn],w[maxn],ans; 13 inline int read() 14 { 15 int x=0;char ch=getchar(); 16 while(ch>‘9‘||ch<‘0‘)ch=getchar(); 17 while(ch<=‘9‘&&ch>=‘0‘){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} 18 return x; 19 } 20 struct node{ 21 int id,res,det; 22 }b[maxn]; 23 bool cmp(node x,node y){return x.res<y.res;} 24 int t[maxn];//还有多少活着 25 inline int ask(int x) 26 { 27 int ret=0; 28 for(;x;x-=(x&-x)) 29 ret+=t[x]; 30 return ret; 31 } 32 inline void add(int x,int w) 33 { 34 for(;x<=n;x+=(x&-x)) 35 t[x]+=w; 36 } 37 signed main() 38 { 39 //freopen("data","r",stdin); 40 n=read(),m=read(),k=read(); 41 for(int i=1;i<=n;++i) 42 b[i].res=k-read(),b[i].id=i; 43 for(int i=1;i<=n;++i) 44 b[i].det=read(); 45 for(int i=1;i<=n;++i) 46 b[i].res=(b[i].res)/b[i].det+1; 47 sort(b+1,b+n+1,cmp); 48 int ans=0; 49 for(int i=1;i<=n;++i) 50 add(i,1); 51 for(int i=1;i<=n;++i) 52 { 53 int las=ans; 54 int res_num=n-i+1; 55 b[i].res-=ans; 56 if(b[i].res<0){ 57 add(b[i].id,-1); 58 continue; 59 }//注意判断<0的情况 60 ans+=b[i].res/res_num; 61 b[i].res%=res_num; 62 int bef=ask(b[i].id); 63 if(bef<=b[i].res) 64 ans++; 65 if(ans>las+m)ans=las+m;//取个min 66 add(b[i].id,-1); 67 68 } 69 printf("%lld\n",ans); 70 }
原题,就是建图稍恶心
标签:min cstring https gis htm ide 不能 efi 十分
原文地址:https://www.cnblogs.com/casun547/p/11373400.html