09.27 打卡

poj 3672
改了许久主要是 区间更新时的范围有弄错了。。
还有 l,r 写反了。。。。
每回线段树都要调很久怎么破。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
//by mars_ch
struct data
{
    int l,r;
    int lsum,rsum,sum;
    int cover;
}line[50005*8];
void build(int l,int r,int num)
{
    line[num].cover=-1;
    line[num].lsum=line[num].rsum=line[num].sum=r-l+1;

    if(l == r) return;

    int mid=(l+r)/2;
    build(l,mid,num*2);
    build(mid+1,r,num*2+1);
}
void pushdown(int num,int k)
{
    if(line[num].cover!=-1)
    {
        line[num*2].cover=line[num*2+1].cover=line[num].cover;
        line[num*2].lsum=line[num*2].rsum=line[num*2].sum=line[num].cover?0:k-(k/2);//左子树的前半部分和后半部分 
        line[num*2+1].lsum=line[num*2+1].rsum=line[num*2+1].sum=line[num].cover?0:(k/2);
        line[num].cover=-1;
    }
}
void pushup(int num,int k)
{
    line[num].lsum=line[num*2].lsum;
    line[num].rsum=line[num*2+1].rsum; 
    if (line[num].lsum == k-k/2)
        line[num].lsum += line[num*2+1].lsum;
    if (line[num].rsum == k/2)
         line[num].rsum += line[num*2].rsum;

    line[num].sum = max(line[num*2].rsum+line[num*2+1].lsum, max(line[num*2].sum, line[num*2+1].sum));
}
void updata(int l,int r,int L,int R,int num,int op)
{
    //printf("first %d %d %d %d\n",l,r,L,R);
    if(l<=L && r>=R)
    {
        line[num].lsum=line[num].rsum=line[num].sum=op?0:R-L+1;
        line[num].cover=op;

        return;
    }
    pushdown(num,R-L+1);
    //printf("second %d %d\n",l,r);
    int mid=(L+R)/2;
    if(l<=mid) updata(l,r,L,mid,num*2,op);
    if(r>mid) updata(l,r,mid+1,R,num*2+1,op);
    //printf("third %d %d\n",l,r);
    pushup(num,R-L+1);
}
int query(int x,int l,int r,int num)
{
    if(l ==r ) return 1;

    pushdown(num,r-l+1); 
    int mid=(l+r)/2;
    if(line[num*2].sum>=x)
    {
        return query(x,l,mid,num*2);
    }
    else if(line[num*2].rsum+line[num*2+1].lsum>=x)
    {
        return mid-line[num*2].rsum+1;
    }
    else
    {
        return query(x,mid+1,r,num*2+1);
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        int op;
        scanf("%d",&op);
        if(op == 1)
        {
            int a;
            scanf("%d",&a);
            if(line[1].sum<a) printf("0\n"); 
            else
            {
                int pos=query(a,1,n,1);
                printf("%d\n",pos);
                updata(pos,pos+a-1,1,n,1,1);
                /*for(int i=1;i<=25;i++)
                {
                    printf("%d %d %d\n",line[i].sum,line[i].lsum,line[i].rsum);
                } */
             }
        } 
        else
        {
            int a,b;
            scanf("%d%d",&a,&b);
            /*for(int i=1;i<=25;i++)
            {
                printf("%d %d %d\n",line[i].sum,line[i].lsum,line[i].rsum);
            } */
            updata(a,a+b-1,1,n,1,0);
            /*for(int i=1;i<=25;i++)
            {
                printf("%d %d %d\n",line[i].sum,line[i].lsum,line[i].rsum);
            } */
        }
    }
}

poj 3666

一道dp题,最近dp差得要疯掉。

打算刷刷题。

这道 不知道为什么,知道状态转移怎么写。但是总是觉得不对劲

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
//by mars_ch
long long dp[2001][2001];
int a[2001];
int b[2001];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++)
    {
        long long mn=dp[i-1][1];
        for(int j=1;j<=n;j++)
        {
            mn=min(mn,dp[i-1][j]);
            dp[i][j]=mn+abs(a[i]-b[j]);
        }
    }
    long long ans=0x3fffffff;
    for(int i=1;i<=n;i++)
    {
        ans=min(ans,dp[n][i]);
    }
    printf("%lld\n",ans);
}

poj 3669
一道bfs没啥好说的 但是打算优化一下常数。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
//by mars_ch
int dx[5]={0,0,1,-1};
int dy[5]={1,-1,0,0};
int time[305][305];
int dis[305][305];
int vis[305][305];
int n;
queue<pair<int,int> >q;
void minn(int x,int y,int t)
{
    if(time[x][y]!=-1)
    {
        time[x][y]=min(time[x][y],t);
    }
    else time[x][y]=t;
}
int main()
{
    memset(time,-1,sizeof(time));
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y,t;
        scanf("%d%d%d",&x,&y,&t);
        minn(x,y,t);
        if(x-1>=0) minn(x-1,y,t);
        minn(x+1,y,t); 
        if(y-1>=0) minn(x,y-1,t);
        minn(x,y+1,t);
    }
    /*for(int i=0;i<=4;i++)
    {
        for(int j=0;j<=4;j++)
        {
            printf("%d ",time[i][j]); 
        }
        puts(""); 
    }*/
    q.push(make_pair(0,0)); 
    vis[0][0]=1;
    while(!q.empty())
    {
        pair<int,int> P=q.front();
        q.pop();
        int x=P.first,y=P.second;
        //printf("%d %d %d\n",x,y,time[x][y]); 
        if(time[x][y] == -1)
        {
            printf("%d\n",dis[x][y]);
            return 0;
        }
        for(int i=0;i<4;i++)
        {
            int nx=x+dx[i];
            int ny=y+dy[i];

            if(vis[nx][ny]) continue;
            if(nx<0 || ny<0 || ny>=304 || nx>=304) continue;
            if((time[nx][ny]<=dis[x][y]+1) && time[nx][ny]!=-1)
            {
                vis[nx][ny]=1;
                continue;
            }
            dis[nx][ny]=dis[x][y]+1;
            vis[nx][ny]=1;

            q.push(make_pair(nx,ny));
        }
    }
    printf("%d\n",-1);
}

poj 3672
一直以为要输出最远走多少。zz
原来是方案数。
提醒我们不要看错题。
orz看错就真的跪了。

#include <iostream>  
#include <string>  
using namespace std;  

char unit[100005];  

int main()  
{  
    int m, t, u, f, d, i, ans = 0, sum = 0;  
    cin >> m >> t >> u >> f >> d;  
    for (i = 0; i < t; i++)  
        cin >> unit[i];  
    for (i = 0; i < t; i++)  
    {  
          if (unit[i] == 'u')  
          {  
              sum += u + d;  
              ans++;  
          }  
          else if (unit[i] == 'f')  
          {  
               sum += f + f;  
               ans++;  
          }  
          else if (unit[i] == 'd')  
          {  
               sum += d + u;  
               ans++;  
          }  
          if (sum > m)  
          {  
               cout << ans-1 << endl;  
               break;  
          }  
    }  
}

poj 3671 类似啊

#include<cstdio>
#include<algorithm>
#include<cstring>
//by mars_ch
using namespace std;
int n;
int a[30005];
int dp[30005][3];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]); 
    }
    int minn=0x3fffffff;
    dp[1][1]=1,dp[1][2]=1;
    dp[1][a[1]]=0;
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=2;j++)
        {
            minn=0x3fffffff;
            for(int k=1;k<=j;k++)
            {
                minn=min(minn,dp[i-1][k]);
            }
            if(a[i] == j) dp[i][j]=minn;
            else dp[i][j]=minn+1;
        }
    }
    printf("%d\n",min(dp[n][1],dp[n][2]));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值