简单dp

HDU - 1029

给定长为n的数组,求出现次数大于等于(n+1)/2的数

ac:

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int ans=0,cnt=0,x;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(cnt==0)
            {
                cnt++;
                ans=x;
            }
            else{
                if(x==ans)
                    cnt++;
                else
                    cnt--;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

hdu-1260

简单dp,要注意前导0,和上午下午

ac:

#include<bits/stdc++.h>
#define MAXN 10005
using namespace std;
 
int dp[MAXN]={0};
int a[MAXN]={0};
int b[MAXN]={0};
 
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=2;i<=n;i++)
            scanf("%d",&b[i]);
        dp[1]=a[1];
        for(int i=2;i<=n;i++)
            dp[i]=min(dp[i-2]+b[i],dp[i-1]+a[i]);
        int aa=dp[n]/3600;
        int bb=dp[n]%3600;
        int cc=bb/60;
        int dd=bb%60;
        if(aa+8>=12)
            printf("%02d:%02d:%02d pm\n",8+aa,cc,dd);
        printf("%02d:%02d:%02d am\n",8+aa,cc,dd);
    }
    return 0;
}

hdu-1176

基础dp,类似数塔,但要注意因为t=0时刻,从5位置开始,所以只能逆向dp,才能保证最后从5出来

ac:

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
 
int dp[MAXN][11]={0};
 
int main()
{
    int n,t,x,maxt;
    while(scanf("%d",&n)&&n)
    {
        maxt=0;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&x,&t);
            dp[t][x]++;
            maxt=max(maxt,t);
        }
        for(int i=0;i<=10;i++)
        {
            if(i<4||i>6)
                dp[0][i]=0;
        }
        for(int i=maxt-1;i>=0;i--)
        {
            dp[i][10]+=max(dp[i+1][9],dp[i+1][10]);
            dp[i][0]+=max(dp[i+1][0],dp[i+1][1]);
            for(int j=1;j<=9;j++)
                dp[i][j]+=max(dp[i+1][j-1],max(dp[i+1][j],dp[i+1][j+1]));
        }
        int ans=0;
        cout<<dp[0][5]<<endl;
    }
    return 0;
}

hdu1058

dp写法:

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string.h>
#define ll long long
#define MAXN 5843
using namespace std;
 
int dp[MAXN]={0};
 
int main()
{
    dp[1]=1;
    int a=1,b=1,c=1,d=1;
    for(int i=2;i<=5842;i++)
    {
        dp[i]=min(dp[a]*2,min(dp[b]*3,min(dp[c]*5,dp[d]*7)));
        if(dp[i]==dp[a]*2)
            a++;
        if(dp[i]==dp[b]*3)
            b++;
        if(dp[i]==dp[c]*5)
            c++;
        if(dp[i]==dp[d]*7)
            d++;
    }
    int n;
    while(scanf("%d",&n)!=EOF&&n)
    {
        cout<<"The ";
        cout<<n;
        if(n%10==1&&n%100!=11)
            cout<<"st ";
        else if(n%10==2&&n%100!=12)
            cout<<"nd ";
        else if(n%10==3&&n%100!=13)
            cout<<"rd ";
        else cout<<"th ";
        cout<<"humble number is "<<dp[n]<<"."<<endl;
    }
    return 0;
}

优先队列写法,要用set判重复

#include<bits/stdc++.h>
#define ll long long
#define MAXN 6000
using namespace std;
 
ll ans[MAXN]={0};
ll a[4]={2,3,5,7};
set<ll> s;
 
void solve()
{
    priority_queue<ll,vector<ll>,greater<ll>> que;
    ans[1]=1;
    que.push(1);
    int k=1;
    while(!que.empty())
    {
        ll t=que.top();
        ans[k++]=t;
        if(k>5842)
            break;
        que.pop();
        for(int i=0;i<4;i++)
        {
            ll g=t*a[i];
            if(s.count(g)==0)
            {
                s.insert(g);
                que.push(g);
            }
        }
    }
}
 
int main()
{
    int n;
    solve();
    while(scanf("%d",&n)&&n!=0)
    {
        cout<<"The ";
        cout<<n;
        if(n%10==1&&n%100!=11)
            cout<<"st ";
        else if(n%10==2&&n%100!=12)
            cout<<"nd ";
        else if(n%10==3&&n%100!=13)
            cout<<"rd ";
        else cout<<"th ";
        cout<<"humble number is "<<ans[n]<<"."<<endl;
    }
    return 0;
}

https://ac.nowcoder.com/acm/problem/21302

题意:

求能被3整除的序列个数

ac:

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define MAXN 105
using namespace std;
char str[MAXN]={0};
ll dp[MAXN][MAXN*10]={0};
 
int main()
{
    scanf("%s",str+1);
    int n=strlen(str+1);
    int maxs=0;
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        int c=str[i]-'0'+3;
        for(int j=0;j<=maxs;j++)
        {
            dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;
            dp[i][j+c]=(dp[i][j+c]+dp[i-1][j])%mod;
        }
        maxs+=c;
    }
    ll ans=0;
    for(int i=1;i<=maxs;i++)
    {
        if(i%3==0)
            ans=(ans+dp[n][i])%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

Easy Problem

题意:

给定一个字符串,让你删除一些字符,使得字符串中没有hard序列,删除每个字符都有一定的代码,求最小代价

解析:

要满足hard 先要满足har 要满足har 先要满足ha 以此类推

dp[i][1]=dp[i-1][1]+a[i]

dp[i][2]=max(dp[i-1][1],dp[i-1][2]+a[i])

dp[i][3]=max(dp[i-1][2],dp[i-1][3]+a[i])

dp[i][4]=max(dp[[i-1][3],dp[i-1][4]+a[i])

#include<bits/stdc++.h>
#define ll long long
#define MAXN 400005
using namespace std;
char pp[MAXN];
int a[MAXN];
ll dp[MAXN][6];
char pos[]="0hard";

int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",pp+1);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int len=strlen(pos);
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=len;j++)
        {
            dp[i][j]=dp[i-1][j];
            if(pp[i]==pos[j])
            {
                if(j==1)
                    dp[i][j]=dp[i-1][j]+a[i];
                else
                    dp[i][j]=min(dp[i][j-1],dp[i-1][j]+a[i]);//min(前缀,当前)
            }
        }
    }
    printf("%lld\n",dp[n][4]);
    return 0;
}
/*
5
hardd
3 3 3 2 2
*/

滚动数组优化:

#include<bits/stdc++.h>
#define ll long long
#define MAXN 400005
using namespace std;
char pp[MAXN];
int a[MAXN];
ll dp[5];
char pos[]="0hard";

int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",pp+1);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int len=strlen(pos);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=len;j++)
        {
            if(pp[i]==pos[j])
            {
                if(j==1)
                    dp[j]=dp[j]+a[i];
                else
                    dp[j]=min(dp[j]+a[i],dp[j-1]);
            }
        }
    }
    printf("%lld\n",dp[len-1]);
    return 0;
}
/*
5
hardd
3 3 3 2 2
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值