書かれたテストの質問、緩い変更、貪欲でダイナミックなプログラミング

トピックの背景:

1、2、5、10、20などの一連の額面の変更があり、その後、お金を支払う必要がある場合、これらの変更を使用して、Zhang Shuの変更の使用を最小限に抑える方法を教えてください。

 

1.貪欲

対象規制:変更額面の倍数が2倍以上の関係を満たす

 

コード:

#include <stdio.h>
#include <algorithm>
const int maxn=101;
int coins[maxn];
#define inc(i,l,r) for(int i=l;i<r;i++)
#define dec(i,r,l) for(int i=r-1;i>=l;i--)

int main(){
	int count;	//面值种数
	scanf("%d",&count);
	inc(i,0,count)	scanf("%d",&coins[i]);
	int X;		//支付金额 
	scanf("%d",&X); 
	
	int ans = 0;
	
	dec(i,count,0){
		int use = X /coins[i];
		ans += use;
		X = X - coins[i] * use;
		printf("需要面额为%d的%d张, ", coins[i], use);
		printf("剩余需要支付RMB %d.\n", X);
	}
	printf("最少需要%d张RMB\n", ans);
	return 0;
}

テスト結果:

 

2.動的プログラミング

額面金額が1、2、5、7、10などの2倍の条件を満たさない場合。

支払い額= 14の場合、貪欲の結果は3(10 + 2 + 2)で、正しい結果は2(7 + 7)です。

このとき、動的計画法が使用されます。

 

アイデア:

1.状態iは、5つの状態i-1、i-2、i-5、i-7、i-10から取得できます。

dp [i] = min(dp [i] -coins [j])+ 1    \ left(0 \ leq i \ leq量、\ right 0 \ leq j \ leqカウント) 

ここで、amountは合計支払い、countは額面金額です。

2.境界dp [0] = 0;

 

コード:
 

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

#define inc(i,l,r) for(int i=l;i<r;i++)

int coinchange(vector<int> &coins,int amount){
	vector<int> dp;
	
	inc(i,0,amount+1)	dp.push_back(-1);
	
	dp[0]=0;
	inc(i,1,amount+1)
		inc(j,0,coins.size()){
			if(i-coins[j]>=0&&dp[i-coins[j]]!=-1){
				if(dp[i]==-1||dp[i-coins[j]]+1<dp[i])
					dp[i]=dp[i-coins[j]]+1;
			}
		} 
		
	return dp[amount];
} 

int main(){
	int amount,coin,count;//支付金额,面额,钱的种类 
	vector<int> coins;

	scanf("%d",&count);	
	inc(i,0,count)	scanf("%d",&coin),coins.push_back(coin);
	scanf("%d",&amount);
	
	printf("%d",coinchange(coins,amount));
	return 0;
}

テスト結果:

 

 

 

元の記事を108件公開 48 件を賞賛 5万回以上の閲覧

おすすめ

転載: blog.csdn.net/larry1648637120/article/details/89057349