码迷,mamicode.com
首页 > 其他好文 > 详细

yp训练赛3/21

时间:2020-03-21 18:28:37      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:one   技术   sorry   names   时间   scanf   color   continue   转移   

A题-饭卡

B题-Balance

C题-待补

D题-待补

E题-Treasure Hunt II

F题-待补

G题-待补

H题-Relocation

I题-Buy the souvenirs

J题-待补

 

A题-饭卡 

返回列表

题意:

即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于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\n",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\n",m-sum-a[n-1]);
44     }
45     return 0;
46 }
View Code

 

 

B题-Balance

返回列表

好像是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\n",dp[m][7500]);
43     }
44     return 0;
45 }
View Code

 

 

E题-Treasure Hunt II

返回列表

题意:

有两个人,有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\n",ans);
37     }
38     return 0;
39 }
View Code

 

 

H题-Relocation

返回列表

题意:

有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:\n",c++);
62         printf("%d\n\n",dp[zhi-1]);
63     }
64   return 0;
65 }
View Code

 

 

I题-Buy the souvenirs

返回列表

题意:

输入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.\n",sum,i);f=1;break;
40             }
41 
42         }
43         if(!f){printf("Sorry, you can‘t buy anything.\n");}
44     }
45   return 0;
46 }
View Code

 

待补

yp训练赛3/21

标签:one   技术   sorry   names   时间   scanf   color   continue   转移   

原文地址:https://www.cnblogs.com/luoyugongxi/p/12540229.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!