PAT.A1068 Encuentra más monedas

Volver a contenidosInserte la descripción de la imagen aquí

Titulo

Hay N monedas y se da el valor de cada moneda. Ahora es necesario usar estas monedas para pagar el valor de M. Pregunte si se puede encontrar una solución para que la suma de los valores de las monedas seleccionadas para el pago sea exactamente M. Si no existe, envíe Sin solución; si existe, seleccione el valor de las monedas utilizadas para el pago de pequeño a grande, y si hay varias soluciones, envíe el pedido lexicográfico más pequeño. El llamado orden lexicográfico se refiere a: hay dos esquemas: {A [1], A [2], ...} y {B [1], B [2], ... Si k≥1, para cualquier i <k tiene A [] -B [pregunta, y A [k] <B [k] se cumple, entonces el orden lexicográfico del esquema A es menor que el del esquema B.

Muestra (se puede copiar)

8 9
5 9 8 7 2 3 4 1
//output
1 3 5
4 8
7 2 4 3
//output
No Solution

Puntos a tener en cuenta

  1. Este problema usa programación dinámica, el problema es 0-1 problema de mochila
#include <bits/stdc++.h>
using namespace std;

int w[10010],dp[110]={0};
bool cho[10011][110],flag[10011];//cho[i][v]用来记录dp[i][v]时选择的策略,flag[i]用来存放第i号物品是否选择
bool cmp(int a,int b){
	return a>b;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    sort(w+1,w+n+1,cmp);
    for(int i=1;i<=n;i++){
    	for(int v=m;v>=w[i];v--){
    		if(dp[v]<=dp[v-w[i]]+w[i]){//放入
    			dp[v]=dp[v-w[i]]+w[i];
    			cho[i][v]=1;
			}else{//不放入
				cho[i][v]=0;
			}
		}
	}
	if(dp[m]!=m)cout<<"No Solution";
	else{
		int k=n,num=0;//num记录选择的总数
		while(k>=0){
			if(cho[k][v]==1){
				flag[k]=true;
				m-=w[k];
				num++;
			}else{
				flag[k]=false;
			}
			k--;
		}
		for(int i=n;i>=1;i--){
			if(flag[i]){
				printf("%d",w[i]);
				num--;
				if(num>0)printf(" ");
			}
		}
	}
	return 0;
}
Publicados 177 artículos originales · ganado elogios 5 · Vistas 6645

Supongo que te gusta

Origin blog.csdn.net/a1920993165/article/details/105595058
Recomendado
Clasificación