最后的几天暑假学习

以后博客以后不应该只是记录些学习知识,应该还有些更重要的东西........

我觉得应该去思考一些什么东西.......

有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式。如:
n=5,5个数分别为1,2,3,4,5,t=5;
那么可能的组合有5=1+4和5=2+3和5=5三种组合方式。
输入
输入的第一行是两个正整数n和t,用空格隔开,其中1<=n<=20,表示正整数的个数,t为要求的和(1<=t<=1000)
接下来的一行是n个正整数,用空格隔开。
输出
和为t的不同的组合方式的数目。
样例输入
5 5
1 2 3 4 5
样例输出
3

这个暴力......

#include<iostream>
using namespace std;
int a[100010],ans=0;
int n,m;
void dfs(int d,int num)
{
    if(d==n+1)
    {
        if(num==m)ans++;
        return ;
    }
    dfs(d+1,num+a[d]);
    dfs(d+1,num);
}
int main()
{
    
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    
    dfs(1,0);
    cout<<ans<<endl;
    return 0;
}

其实这是个背包问题,这个是二维和一维的

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1000];
int dp[1000];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)     
    cin>>a[i];
/*    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(a[i]>j) dp[i][j]=dp[i-1][j];
            else dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];
        }
        for(int j=1;j<=m;j++)
        cout<<dp[i][j]<<"  ";
        cout<<endl;
    }*/
        for(int i=1;i<=n;i++)
    {
        dp[0]=1;
        for(int j=m;j>=a[i];j--)
        {
            dp[j]=dp[j]+dp[j-a[i]];
        }
        for(int j=1;j<=m;j++)
        cout<<dp[j]<<"  ";
        cout<<endl;
    }
    cout<<dp[m];
    return 0;
    
    
}

 背包问题最进又看了下

for(int i=1;i<=n;i++)
{
    for(int j=v;j>=0;j--)
    {
        if(w[i]<=j)
        f[j]=max(f[j],f[j-w[i]]+c[i])
        else 
        f[j]=f[j];
    }
}
for(int i=0;i<n;i++)
{
    for(int j=w[i];j<=v;j++)
    {
        if(w[i]<j)
        f[j]=max(f[j],f[j-w[i]]+c[i]);
        else f[j]=f[j];
    }
}
void zeroonepack(int cost,int weight)
{
    for(int i=V;i>=cost;i--)
    f[i]=max(f[i],f[i-cost]+weight);
}
void completepack(int cost,int weight)
{
    for(int i=cost;i<=V:i++)
    f[i]=max(f[i],f[i-cost]+weight);
}
void multiplepack(int cost,int weight,int mount)
{
    int k;
    if(cost*mount>=V)
    {
        completepack(cost,weight);
        return;
    }
    k=1;
    while(k<mount)
    {
        zeroonepack(k*cost,k*weight);
        mount-=k;
        k*=2;
    }
    zeroonepack(mount*cost,mount*weight);
}
int main()
{
    int n,i;
    cin>>n>>V;
    for(int i=0;i<n;i++) cin>>m+i>>c+i>>w+i;
    for(int i=0;i<n;i++)
    multiplepack(c[i],w[i],m[i]);
    cout<<f[v];
}

POJ - 3061

n个数和m,求最小连续序列和大于m

#include<iostream>
#include<string.h>
#define ll long long
using namespace std;
ll a[1000005]; 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n,m;
        scanf("%lld%lld",&n,&m);
        a[0]=0;
        for(ll i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            a[i]+=a[i-1];
        }
        ll ans=0x3f3f3f;
        for(ll i=1;i<=n;i++)
        {
            ll l=1,r=i,mid;
            while(l<=r)
            {
                mid=(l+r)>>1;
                if(a[i]-a[mid-1]>=m)
                {
                //    cout<<a[i]<<" "<<a[mid-1]<<"xxxxx"<<r-mid+1<<endl;;
                    ans=min(ans,(i-mid+1));
                    l=mid+1;
                }
                else r=mid-1;
            }
        }
        if(ans==0x3f3f3f) cout<<0<<endl;
        else cout<<ans<<endl;
    }
}

HDU 1078

记忆化搜索

#include<bits/stdc++.h>
using namespace std;
int n,k,dp[105][105],a[105][105];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int dfs(int x,int y)
{
    int l,ans=0;
    if(dp[x][y]!=0) return dp[x][y];
    
    for(int i=1;i<=k;i++)
    {
        for(int j=0;j<4;j++)
        {
            int xx=x+dx[j]*i;
            int yy=y+dy[j]*i;
            if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&a[xx][yy]>a[x][y]) 
             ans=max(ans,dfs(xx,yy));
        }
    }
    dp[x][y]=ans+a[x][y];
    return dp[x][y];
}
int main()
{
    while(cin>>n>>k)
    {
        if(n<=0&&k<=0) break;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>a[i][j];
            }
        }
        memset(dp,0,sizeof(dp));
        cout<<dfs(1,1)<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/wpbing/p/9485273.html