当前位置: 代码迷 >> 综合 >> 洛谷 普及/提高- P1024 [NOIP2000 普及组] 税收与补贴问题
  详细解决方案

洛谷 普及/提高- P1024 [NOIP2000 普及组] 税收与补贴问题

热度:101   发布时间:2023-11-27 14:58:54.0

洛谷 普及/提高- P1024 [NOIP2000 普及组] 税收与补贴问题

  • 是一个不好写的模拟,细节问题很多,感觉至少绿题起步。

Link:P1023 [NOIP2000 普及组] 税收与补贴问题

首先题意就是个问题,一般人读不太懂。大概意思就是你需要确定一个最小补贴或者税收使得我第一行政府选择的商品预期价取得的利润比其余任意价格的利润都要高。啥意思呢?看这里我懒得解释了,确实难读懂。对题意的直观说明,有图有真相…

那么首先将所有可能解全部扫描出来,直到销量到达最小(下一次操作会 < = 0 <=0 <=0),统计完所有的情况之后我们假设需要补贴 x x x元,如果是负的那么就是纳税,正的就是补贴。接下来我们需要通过推公式算出 x x x的选择区间,因为最终的值可能是个区间, x x x取值只要处于这个区间内说明利益一定比任意商品价格选择都要高。那么我们需要取最接近 0 0 0的数。难点推公式:我们从最低价位到最高价位开始遍历。那么假设政府要求商品预期价格为 m m m s t st st为商品最低价格那么有: a [ m ] ? ( x + ( m ? s t ) > = a [ i ] ? ( x + ( i ? s t ) ) a[m]*(x+(m-st)>=a[i]*(x+(i-st)) a[m]?(x+(m?st)>=a[i]?(x+(i?st))。我们假设 a n s = ( a [ i ] ? ( i ? s t ) ? a [ m ] ? ( m ? s t ) ) ? 1.0 / ( a [ m ] ? a [ i ] ) ; ans=(a[i]*(i-st)-a[m]*(m-st))*1.0/(a[m]-a[i]); ans=(a[i]?(i?st)?a[m]?(m?st))?1.0/(a[m]?a[i]);那么如果 a [ m ] ? a [ i ] > 0 a[m]-a[i]>0 a[m]?a[i]>0说明符号是正的,那么 a n s ans ans值来更新 x > = a n s x>=ans x>=ans的区间,否则如果 a [ m ] ? a [ i ] < 0 a[m]-a[i]<0 a[m]?a[i]<0说明 a n s ans ans值来更新 x < = a n s x<=ans x<=ans。最后的 [ L , R ] [L,R] [L,R]区间就是 x x x可选区间。

  • 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];
int main(){
    int m;cin>>m;int val,sum;cin>>val>>sum;int st=val;a[val]=sum;int val1,sum1;while(cin>>val1>>sum1,val1!=-1&&sum1!=-1){
    for(int i=val+1;i<=val1;i++){
    a[i]=a[i-1]+(sum1-sum)/(val1-val);}val=val1;sum=sum1;}int d;cin>>d;while(1){
    if(sum-d<0){
    break;}val++;a[val]=sum-d;sum-=d;}double ma=2e9;double mi=-2e9;for(int i=st;i<=val;i++){
    double ans=(a[i]*(i-st)-a[m]*(m-st))*1.0/(a[m]-a[i]);double s=a[m]-a[i];if(s>0){
    mi=max(mi,ans);}else if(s<0){
    ma=min(ma,ans);}}if(ma<0){
    cout<<(int)floor(ma)<<endl;}else if(mi>0){
    cout<<(int)ceil(mi)<<endl;}else{
    cout<<0<<endl;}return 0;
}