ACM实训冲刺第十四天

【碎碎念】今天拼了一下午的积木花,送我一朵小红花


0-1 Knapsack Problem

问题

你有N件东西,你想把它们放进背包里。物品i的价值vi和重量wi。

您希望找到一个项目的子集,以便:这些物品的总价值要尽可能的大。这些物品的总重量最多为W,也就是背包的容量。找出背包中物品的最大总价值。

输入
N W
v1 w1
v2 w2

vN wN
第一行由整数N和w组成。在接下来的几行中,给出第i项的值和权重。

输出
打印一行中项目的最大总价值。

约束
1≤n≤100
1≤vi≤1000
1≤wi≤1000
1≤w≤10000
输入1
4个5
4个2
5个2
2 1
8 3
示例输出1
13

样本输入2
2 20

思路

与第一套的第四题类似,代码无改变

只是输入w和d的位置有所改变

代码

#include <stdio.h>
int main(){
	//第一行输入 两个空格分隔的整数
	int n,m;
	scanf("%d %d",&n,&m) ;
	//定义状态
	int dp[12881] ;
	//初始化dp[i]=0 
	for(int i=0;i<=m;i++){
		dp[i]=0;
	}
	//转移方程
	for(int i=1;i<=n;i++) {//注意  i=1 
		//定义重量和价值 两个空格分隔的整数描述魅力i: W i和D i
		int w,d;
		scanf("%d %d",&d,&w) ;//更改输入位置
		for(int j=m;j>=w;j--){//注意j>=w
			if(dp[j-w]+d>dp[j])
				dp[j]=dp[j-w]+d;
		}
	}
	printf("%d\n",dp[m]);
	return 0;
}
#include <stdio.h>
int main(){
	//第一行输入 两个空格分隔的整数
	int n,m;
	scanf("%d %d",&n,&m) ;
	//定义状态
	int dp[10001] ;
	//初始化dp[i]=0 
	for(int i=0;i<=m;i++){
		dp[i]=0;
	}
	//转移方程
	for(int i=1;i<=n;i++) {//注意  i=1 
		//定义重量和价值 两个空格分隔的整数描述魅力i: W i和D i
		int w[101],d[101];//更改为数组类型 
		scanf("%d %d",&d[i],&w[i]) ;//输入改变 
		for(int j=m;j>=w[i];j--){//注意j>=w
			if(dp[j-w[i]]+d[i]>dp[j])
				dp[j]=dp[j-w[i]]+d[i];
		}
	}
	printf("%d\n",dp[m]);
	return 0;
}

Election Time

问题

奶牛们在推翻了暴君农场主约翰后进行了第一次选举,贝茜是N头奶牛(1≤N≤50000头)竞选总统之一。然而,在选举真正开始之前,贝西想确定谁最有可能获胜。

选举包括两轮。在第一轮中,获得最多票数的K头奶牛(1≤K≤N)进入第二轮。在第二轮投票中,得票最多的奶牛成为总统。

假设奶牛i预计在第一轮获得Ai票(1≤Ai≤1000,000,000),在第二轮获得Bi票(1≤Bi≤1000,000,000)(如果它成功了),确定哪头奶牛预计会赢得选举。值得庆幸的是,Ai列表中没有出现两次投票计数;同样,在Bi名单中没有出现两次投票计数。

输入
*第一行:两个空格分隔的整数:N和K
*第2行…N+1:第i+1行包含两个空格分隔的整数:Ai和Bi

输出
*第一行:预计将赢得选举的牛的指数。

思路 

选举两轮-->双重循环

题目意思,一些牛进行竞选,竞选两次,第一次有K只牛入围,第二次竞选从入围的牛进行竞选第一名。

思路,改进快速排序,进行两次即可,不多说了具体代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;

// 定义结构体node,包含任务的两个属性a、b及任务编号num
struct node
{
    int a, b, num;
} s[50010];

// 比较函数cmpa,按a降序,若a相同则按b降序
int cmpa(node a, node b)
{
    if (a.a == b.a) return a.b > b.b; // a相同时比较b
    return a.a > b.a;                // 直接比较a
}

// 比较函数cmpb,仅按b降序
int cmpb(node a, node b)
{
    if (a.b == b.b) return a.a > b.a; // b相同时比较a
    return a.b > b.b;                // 直接比较b
}

int main()
{
    int i, n, k;

    // 循环读取输入,直到文件结束
    while (scanf("%d%d", &n, &k) != EOF)
    {
        // 读取n个任务的属性a和b
        for (i = 0; i < n; ++i)
        {
            scanf("%d%d", &s[i].a, &s[i].b);
            s[i].num = i + 1; // 记录任务编号
        }

        // 首先按属性a降序排序所有任务
        sort(s, s + n, cmpa);

        // 然后在前k个任务中按属性b降序排序
        sort(s, s + k, cmpb);

        // 输出排序后的前k个任务中a属性最大任务的编号
        printf("%d\n", s[0].num);
    }

    return 0;
}

代码

#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
    int a,b,num;
} s[50010];
int cmpa(node a, node b)
{
    if (a.a == b.a) return a.b > b.b;
    return a.a > b.a;
}
int cmpb(node a, node b)
{
    if (a.b == b.b) return a.a > b.a;
    return a.b > b.b;
}
int main()
{
    int i,n,k;
    while (scanf("%d%d", &n, &k) != EOF)
    {
        for (i = 0; i < n; ++i)
        {
            scanf("%d%d", &s[i].a, &s[i].b);
            s[i].num = i + 1;
        }
        sort(s, s + n, cmpa);
        sort(s, s + k, cmpb);
        printf("%d\n", s[0].num);
    }
    return 0;
}

 


寒冰王座

代码

注意大于小于

#include<stdio.h>
int main(){
	int t;
	scanf("%d",&t) ;
	for(int i=0;i<t;i++){
		int n;
		scanf("%d",&n);
		int ans=0;
		if(n>=300) ans=n%50;
		else if(n>=200&&n<300) ans=n-200;
		else if(n>=150&&n<200) ans=n-150;
		else if (n<150)ans=n;
		printf("%d\n",ans);
	}
	return 0;
}

Charm Bracelet

代码

 与0-1一样 (ACM实训0-1背包问题70%可能性必考)

#include<stdio.h>
int main(){
	int n,m;
	int dp[12881];
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		dp[i]=0;
	}
	for(int i=1;i<=n;i++){
		int w,d;
		scanf("%d %d",&w,&d);
		for(int j=m;j>=w;j--){
			if(dp[j-w]+d>dp[j])
				dp[j]=dp[j-w]+d;
		}
	}
	printf("%d\n",dp[m]);
	return 0;
}

 Anton and Letters

代码

#include<stdio.h>
int main(){
	int flag[26];
	for(int i=0;i<26;i++){
		flag[i]=0;
	}
	char tmp;
	while(tmp!='}'){
		scanf("%c",&tmp);
		if(tmp=='}') break;
		if(tmp<='z'&&tmp>='a'){
			flag[tmp-'a']++;
		}
	}
	int cnt=0;
	for(int i=0;i<26;i++){
		if(flag[i]>0) cnt++;
	}
	printf("%d",cnt);
	return 0;
}

Sum of Digits

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char s[100000];
int result = 0;
int sum = 0;
int main(){
    scanf("%s",&s);
    while(1){
        if(strlen(s)==1) 
            break;
        sum=0;
        for(int i=0;i < strlen(s); i++){
            sum+=s[i]-'0';
        }
        itoa(sum ,s ,10);
        result++;
    }
    printf("%d",result);
    return 0;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值