计数类dp
https://www.acwing.com/problem/content/11/
01背包最优解计数
#include<bits/stdc++.h>
using namespace std ;
const int N = 1009 , mod = 1e9 + 7;
int dp[N] , cnt[N];//容量为j的最大价值的方案数
int n , v ;
int w[N] , val[N];
int main(){
cin >> n >> v;
for(int i = 1 ; i <= n ; i++){
cin >> w[i] >> val[i] ;
}
for(int i = 0 ; i <= v ; i++){
cnt[i] = 1 ;
}
for(int i = 1 ; i <= n ; i++){
for(int j = v ; j >= w[i] ; j--){
int t = dp[j-w[i]] + val[i] ;
if(t > dp[j]){
dp[j] = t ;
cnt[j] = cnt[j-w[i]];
}else if(t == dp[j]){
cnt[j] += cnt[j-w[i]];
cnt[j] %= mod ;
}
}
}
cout << cnt[v] << endl;
}
该题与最短路计数思想差不多
https://www.luogu.com.cn/problem/P1608
#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std ;
typedef long long ll ;
const int N = 2010, M = 4000009 ;
int e[M] , ne[M] , w[M] , h[N] , idx ;
void add(int a , int b , int c){
e[idx] = b , w[idx] = c , ne[idx] = h[a] , h[a] = idx++;
}
typedef pair<int,int> PII;
int ma[N][N];
int dis[N];
int cnt[N];
int n , m;
void dijkstra(int u){
priority_queue<PII , vector<PII> , greater<PII>>q;
memset(dis , 0x3f , sizeof(dis));
dis[u] = 0 ;
cnt[u] = 1 ;
q.push({dis[u] , u});
while(q.size()){
auto x = q.top() ; q.pop() ;
int u = x.second , d = x.first ;
for(int i = h[u] ; ~i ; i = ne[i]){
int j = e[i] ;
if(dis[j] > d + w[i]){
dis[j] = d + w[i] ;
cnt[j] = cnt[u] ;
q.push({dis[j] , j});
}else if(dis[j] == d + w[i]){
cnt[j] += cnt[u] ;
}
}
}
if(cnt[n]){
cout << dis[n] << " " << cnt[n] << endl;
}else{
puts("No answer");
}
}
void solve(){
memset(h , -1 , sizeof(h));
scanf("%d%d" , &n , &m);
for(int i = 1 ; i <= m ; i++){
int a , b , c ;
scanf("%d%d%d" , &a , &b , &c);
if(ma[a][b] == 0 || ma[a][b] > c){
add(a , b , c);
ma[a][b] = c ;
}
}
dijkstra(1);
}
signed main(){
#ifdef ONLINE_JUDGE
#else
freopen("D:\\c++\\in.txt", "r", stdin);
//freopen("D:\\c++\\out.txt", "w", stdout);
#endif
solve();
}