yp训练赛3/21
Posted luoyugongxi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yp训练赛3/21相关的知识,希望对你有一定的参考价值。
C题-待补
D题-待补
F题-待补
G题-待补
J题-待补
题意:
即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)
有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
思路:
卡上余额先减5块,价格排序,去掉最大值,然后01背包,这里有一个坑点,余额事先小于5块,直接输出余额,不用再去算了
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define il inline 6 #define it register int 7 #define inf 0x3f3f3f3f 8 #define lowbit(x) (x)&(-x) 9 #define pii pair<int,int> 10 #define mak(n,m) make_pair(n,m) 11 #define mem(a,b) memset(a,b,sizeof(a)) 12 #define mod 998244353 13 #define fi first 14 #define se second 15 #define sz(x) (int)(x).size() 16 #define all(x) (x).begin(), (x).end() 17 const int maxn=1e4+10; 18 int t,n,a[maxn],m; 19 int dp[maxn]; 20 int main() { 21 while(~scanf("%d",&n)){ 22 if(n==0){break;} 23 for(it i=0;i<n;i++){ 24 scanf("%d",&a[i]); 25 } 26 scanf("%d",&m); 27 sort(a,a+n); 28 mem(dp,0); 29 dp[0]=1; 30 int mm=m-5; 31 if(mm<0){printf("%d ",m);continue;} 32 for(it j=0;j<n-1;j++){ 33 for(it i=mm;i>=1;i--){ 34 if(i-a[j]>=0 && dp[i-a[j]]){ 35 dp[i]=dp[i-a[j]]; 36 } 37 } 38 } 39 int sum=0; 40 for(it i=mm;i>=0;i--){ 41 if(dp[i]){sum=i;break;} 42 }//cout<<sum<<endl; 43 printf("%d ",m-sum-a[n-1]); 44 } 45 return 0; 46 }
好像是hdu题目,做过的
题意:
就是给你n个勾子位置,m个砝码,问有多少平衡的情况
思路:
因为左边是负数,所以把20*15*25==7500扩大一倍0~7499代表左边,7501~15000代表右边,差不多背包套一下就过了
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 using namespace std; 5 #define ll long long 6 #define ull unsigned long long 7 #define il inline 8 #define it register int 9 #define inf 0x3f3f3f3f 10 #define lowbit(x) (x)&(-x) 11 #define pii pair<int,int> 12 #define mak(n,m) make_pair(n,m) 13 #define mem(a,b) memset(a,b,sizeof(a)) 14 #define mod 998244353 15 #define fi first 16 #define se second 17 #define sz(x) (int)(x).size() 18 #define all(x) (x).begin(), (x).end() 19 const int maxn=1e4+10; 20 int n,m,c[25],g[25]; 21 int dp[25][15010]; 22 int main() { 23 while(~scanf("%d%d",&n,&m)){ 24 for(it i=0;i<n;i++){ 25 scanf("%d",&c[i]); 26 } 27 for(it i=1;i<=m;i++){ 28 scanf("%d",&g[i]); 29 } 30 mem(dp,0);dp[0][7500]=1; 31 for(it i=1;i<=m;i++){ 32 for(it j=0;j<=15000;j++){ 33 if(dp[i-1][j]){ 34 for(it k=0;k<n;k++){ 35 if(j+g[i]*c[k]>=0 && j+g[i]*c[k]<=15000){ 36 dp[i][j+g[i]*c[k]]+=dp[i-1][j]; 37 } 38 } 39 } 40 } 41 } 42 printf("%d ",dp[m][7500]); 43 } 44 return 0; 45 }
题意:
有两个人,有n个城堡,城堡每个都有黄金w,城堡两两连接,距离都是1
两个人的距离不能超过m,他们有 t 天可以探索城堡得到黄金,问他们最多能得到多少黄金
题目给了两人的初始点(两个人刚开始在一起),在初始点不需要花费时间就可以得到这座城堡的黄金。
思路:
肯定是从初始点左右先扩大长度,然后再判断往左还是往右得到的黄金多。模拟即可边界不能超过……
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 #define ll long long 7 #define ull unsigned long long 8 #define il inline 9 #define it register int 10 #define inf 0x3f3f3f3f 11 #define lowbit(x) (x)&(-x) 12 #define pii pair<int,int> 13 #define mak(n,m) make_pair(n,m) 14 #define mem(a,b) memset(a,b,sizeof(a)) 15 #define mod 998244353 16 #define fi first 17 #define se second 18 #define sz(x) (int)(x).size() 19 #define all(x) (x).begin(), (x).end() 20 const int maxn=1e5+10; 21 int t,n,pos,m; 22 ll a[maxn]; 23 int main() { 24 while(~scanf("%d%d",&n,&pos)){a[0]=0; 25 for(it i=1;i<=n;i++){scanf("%lld",&a[i]);a[i]+=a[i-1];} 26 scanf("%d%d",&m,&t); 27 ll ans=0; 28 for(it i=max(1,pos-t);i<=pos;i++){ 29 int pos2=min(i+m,pos+t);pos2=min(pos2,n); 30 ll sum=a[pos2]-a[i-1];//cout<<pos2<<sum<<endl; 31 int pos3=t-max(pos-i,pos2-pos); 32 ll sum1=sum+a[i-1]-a[max(i-pos3-1,0)]; 33 ll sum2=sum+a[min(n,pos2+pos3)]-a[pos2]; 34 ans=max(ans,max(sum1,sum2));//cout<<ans<<sum1<<sum2<<endl; 35 } 36 printf("%lld ",ans); 37 } 38 return 0; 39 }
题意:
有n件物品(n<=10),有两辆车分别可以载不大于c1或者c2大小的物品,物品大小不会超过c1或者c2的。
两辆车同时出发回来,算一趟,问最少几趟可以运完
思路:
因为n<=10,可以暴力枚举出所有一趟运输的可能性fangan[],这些可能性用状态压缩保存,这里有一个状态转移方程
dp[ j | fangan[i] ]=min(dp[j]+1,dp[j | fangan[i]] );这个方程要满足j 和 fangan[i]没有交集,就是没有重复送同一件物品
可以得到dp[(1<<n)-1]就是最少的运输方案
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 #define ll long long 7 #define ull unsigned long long 8 #define il inline 9 #define it register int 10 #define inf 0x3f3f3f3f 11 #define lowbit(x) (x)&(-x) 12 #define pii pair<int,int> 13 #define mak(n,m) make_pair(n,m) 14 #define mem(a,b) memset(a,b,sizeof(a)) 15 #define mod 998244353 16 #define fi first 17 #define se second 18 #define sz(x) (int)(x).size() 19 #define all(x) (x).begin(), (x).end() 20 const int maxn=(1<<10)+10; 21 int t,n,m,c1,c2; 22 int dp[maxn],vis[15],a[15],fan[maxn]; 23 bool cmp(int a,int b){return a>b;} 24 bool check(int zhi){ 25 int sum=0,ge=0; 26 for(it i=0;i<n;i++){ 27 if(zhi&(1<<i)){sum+=a[i];vis[ge++]=a[i];} 28 } 29 if(sum>c1+c2){return 0;} 30 int zhh=1<<ge; 31 for(it i=1;i<zhh;i++){ 32 int ans=0; 33 for(it j=0;j<ge;j++){ 34 if(i&(1<<j)){ans+=vis[j];} 35 } 36 //cout<<ans<<" "<<sum-ans<<endl; 37 if(ans<=c1 && sum-ans<=c2){return 1;} 38 if(ans<=c2 && sum-ans<=c1){return 1;} 39 } 40 return 0; 41 } 42 int main(){ 43 scanf("%d",&t);int c=1; 44 while(t--){ 45 scanf("%d%d%d",&n,&c1,&c2); 46 for(it i=0;i<n;i++){scanf("%d",&a[i]);} 47 int zhi=1<<n,ge=0; 48 for(it i=1;i<zhi;i++){//cout<<i<<" :"<<endl; 49 if(check(i)){ 50 fan[ge++]=i; 51 } 52 } 53 mem(dp,inf);dp[0]=0; 54 for(it i=0;i<ge;i++){ 55 for(it j=zhi-1;j>=0;j--){ 56 if((j&fan[i])==0){ 57 dp[j|fan[i]]=min(dp[j]+1,dp[j|fan[i]]); 58 } 59 } 60 } 61 printf("Scenario #%d: ",c++); 62 printf("%d ",dp[zhi-1]); 63 } 64 return 0; 65 }
题意:
输入n,m
有n个硬币
给n个价值为ai的硬币,求最多个数的硬币,其中价值不超过m的有多少种。如果没有输出Sorry, you can‘t buy anything.
思路:
dp【i】【j】i表示个数,j表示价值,如果dp【i-1】【j-ai】>0,那么dp【i】【j】+=dp【i-1】【j-ai】
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 #define ll long long 7 #define ull unsigned long long 8 #define il inline 9 #define it register int 10 #define inf 0x3f3f3f3f 11 #define lowbit(x) (x)&(-x) 12 #define pii pair<int,int> 13 #define mak(n,m) make_pair(n,m) 14 #define mem(a,b) memset(a,b,sizeof(a)) 15 #define mod 998244353 16 #define fi first 17 #define se second 18 #define sz(x) (int)(x).size() 19 #define all(x) (x).begin(), (x).end() 20 const int maxn=1e5+10; 21 int t,n,m,a; 22 int dp[40][510]; 23 int main(){ 24 scanf("%d",&t); 25 while(t--){ 26 scanf("%d%d",&n,&m); 27 memset(dp,0,sizeof(dp)); 28 dp[0][0]=1; 29 for(it i=1;i<=n;i++){ scanf("%d",&a); 30 for(it j=m;j>=a;j--) 31 for(it k=i;k>=1;k--) 32 if(dp[k-1][j-a]>0) 33 dp[k][j]+=dp[k-1][j-a]; 34 } 35 int f=0,sum=0; 36 for(it i=n;i>=1;i--){ 37 for(it j=0;j<=m;j++){sum+=dp[i][j];} 38 if(sum>0){ 39 printf("You have %d selection(s) to buy with %d kind(s) of souvenirs. ",sum,i);f=1;break; 40 } 41 42 } 43 if(!f){printf("Sorry, you can‘t buy anything. ");} 44 } 45 return 0; 46 }
待补
以上是关于yp训练赛3/21的主要内容,如果未能解决你的问题,请参考以下文章