【动态规划】 基础题目(一)

1、P1359 租用游艇

#include<bits/stdc++.h>
using namespace std;
int dp[205],n,x;
int main()
{
	freopen("a.in","r",stdin);
	memset(dp,0x3f,sizeof(dp));
	scanf("%d",&n); dp[1]=0;
	for(int i=1;i<=n;i++)
		for(int j=1+i;j<=n;j++)
		{
			scanf("%d",&x);
			dp[j]=min(dp[i]+x,dp[j]);
		}
	printf("%d\n",dp[n]);
	return 0;
}

2、 P1060 开心的金明

01背包

#include<bits/stdc++.h>
using namespace std;
int dp[30005];
int w[26],c[26],m,n;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d",&w[i],&c[i]);
	for(int i=1;i<=m;i++)
		for(int j=n;j>=w[i];j--)
			dp[j]=max(dp[j],dp[j-w[i]]+c[i]*w[i]);
	printf("%d",dp[n]);
	return 0;
}

3、 P1757 通天之分组背包

分组背包

#include<bits/stdc++.h>
using namespace std;
int group,dp[1005],w[1005],c[1005],number[1005][1005],cnt[1005],n,m;
int main()
{
	scanf("%d%d",&n,&m);
	int z;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&w[i],&c[i],&z);
		cnt[z]++;
		group=max(group,z);
		number[z][cnt[z]]=i;
	}
	for(int i=1;i<=group;i++)
		for(int j=n;j>=0;j--)
		 	for(int k=1;k<=cnt[i];k++)
		 		if(j>=w[number[i][k]])
		 			dp[j]=max(dp[j],dp[j-w[number[i][k]]]+c[number[i][k]]);
	printf("%d",dp[n]);
	return 0;
}

4、P1077 摆花

设dp[i]表示摆i朵花的方案数,然后对于j的容量,枚举花的种类i,以及放第i种花的个数k,dp[j]+=dp[j-k]

#include<bits/stdc++.h>
using namespace std;
int n,m,a[105],dp[105];
const int mod=1000007;
int main()
{	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	dp[0]=1;
	for(int i=1;i<=n;i++)
		for(int j=m;j>=1;j--)
			for(int k=1;k<=a[i] && j>=k;k++)
				dp[j]=(dp[j]+dp[j-k])%mod,dp[j]%=mod;
	printf("%d\n",dp[m]);
	return 0;
} 

5、P1095 守望者的逃离

这道题目考虑到闪现+等待的平均速度更大,所以优先进行这种操作,而第二次的走路操作来优化等待时间内的数值,由于走路四秒最后还是不如闪现快,所以不影响后面的结论,也就是说 能这样更新,完全是因为闪现+等待的平均速度更大(想了好久)

#include<bits/stdc++.h>
const int maxt=300000+50;
using namespace std;
long f[maxt+1];
int m,s,t;
int main()
{
    scanf("%d %d %d",&m,&s,&t);
    f[0]=0;
    for (int i=1;i<=t;++i)
        if (m>=10) 
        {
            f[i]=f[i-1]+60;
            m-=10;
        }
        else
        {
            f[i]=f[i-1];
            m+=4;
        }
    for (int i=1;i<=t;++i)
    {
        if (f[i]<f[i-1]+17) f[i]=f[i-1]+17;
        if (f[i]>=s)
        {
            printf("Yes\n%d",i);
            return 0;
        }
    } 
    printf("No\n%d",f[t]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/andyc_03/article/details/107579557